@roomi-fields/notebooklm-mcp 1.3.6 → 1.5.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/LICENSE +22 -22
- package/README.md +71 -34
- package/deployment/INDEX.md +292 -0
- package/deployment/PACKAGE-FILES.txt +180 -0
- package/deployment/QUICK-START.md +100 -0
- package/deployment/docs/01-INSTALL.md +611 -0
- package/deployment/docs/02-CONFIGURATION.md +404 -0
- package/deployment/docs/03-API.md +1691 -0
- package/deployment/docs/04-N8N-INTEGRATION.md +373 -0
- package/deployment/docs/05-TROUBLESHOOTING.md +429 -0
- package/deployment/docs/06-NOTEBOOK-LIBRARY.md +692 -0
- package/deployment/docs/07-AUTO-DISCOVERY.md +236 -0
- package/deployment/docs/08-WSL-USAGE.md +363 -0
- package/deployment/docs/09-MULTI-INTERFACE.md +293 -0
- package/deployment/docs/10-CONTENT-MANAGEMENT.md +421 -0
- package/deployment/docs/11-MULTI-ACCOUNT.md +295 -0
- package/deployment/docs/README.md +207 -0
- package/deployment/scripts/README.md +564 -0
- package/deployment/scripts/install.ps1 +114 -0
- package/deployment/scripts/setup-auth.ps1 +217 -0
- package/deployment/scripts/start-server.ps1 +72 -0
- package/deployment/scripts/stop-server.ps1 +51 -0
- package/deployment/scripts/test-api.ps1 +651 -0
- package/deployment/scripts/test-auth.ps1 +323 -0
- package/deployment/scripts/test-auto-discovery.ps1 +295 -0
- package/deployment/scripts/test-cors.ps1 +398 -0
- package/deployment/scripts/test-errors.ps1 +581 -0
- package/deployment/scripts/test-server.ps1 +140 -0
- package/deployment/scripts/test-sessions.ps1 +426 -0
- package/deployment/scripts/test-validation.ps1 +299 -0
- package/dist/accounts/account-manager.d.ts +163 -0
- package/dist/accounts/account-manager.d.ts.map +1 -0
- package/dist/accounts/account-manager.js +614 -0
- package/dist/accounts/account-manager.js.map +1 -0
- package/dist/accounts/auto-login-manager.d.ts +62 -0
- package/dist/accounts/auto-login-manager.d.ts.map +1 -0
- package/dist/accounts/auto-login-manager.js +537 -0
- package/dist/accounts/auto-login-manager.js.map +1 -0
- package/dist/accounts/crypto.d.ts +45 -0
- package/dist/accounts/crypto.d.ts.map +1 -0
- package/dist/accounts/crypto.js +138 -0
- package/dist/accounts/crypto.js.map +1 -0
- package/dist/accounts/index.d.ts +14 -0
- package/dist/accounts/index.d.ts.map +1 -0
- package/dist/accounts/index.js +14 -0
- package/dist/accounts/index.js.map +1 -0
- package/dist/accounts/types.d.ts +103 -0
- package/dist/accounts/types.d.ts.map +1 -0
- package/dist/accounts/types.js +7 -0
- package/dist/accounts/types.js.map +1 -0
- package/dist/auth/auth-manager.d.ts +9 -2
- package/dist/auth/auth-manager.d.ts.map +1 -1
- package/dist/auth/auth-manager.js +60 -6
- package/dist/auth/auth-manager.js.map +1 -1
- package/dist/auto-discovery/auto-discovery.d.ts.map +1 -1
- package/dist/auto-discovery/auto-discovery.js +2 -1
- package/dist/auto-discovery/auto-discovery.js.map +1 -1
- package/dist/cli/accounts.d.ts +13 -0
- package/dist/cli/accounts.d.ts.map +1 -0
- package/dist/cli/accounts.js +195 -0
- package/dist/cli/accounts.js.map +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -1
- package/dist/content/content-generator.d.ts +153 -0
- package/dist/content/content-generator.d.ts.map +1 -0
- package/dist/content/content-generator.js +637 -0
- package/dist/content/content-generator.js.map +1 -0
- package/dist/content/content-manager.d.ts +364 -0
- package/dist/content/content-manager.d.ts.map +1 -0
- package/dist/content/content-manager.js +3841 -0
- package/dist/content/content-manager.js.map +1 -0
- package/dist/content/content-templates.d.ts +183 -0
- package/dist/content/content-templates.d.ts.map +1 -0
- package/dist/content/content-templates.js +719 -0
- package/dist/content/content-templates.js.map +1 -0
- package/dist/content/index.d.ts +14 -0
- package/dist/content/index.d.ts.map +1 -0
- package/dist/content/index.js +14 -0
- package/dist/content/index.js.map +1 -0
- package/dist/content/types.d.ts +285 -0
- package/dist/content/types.d.ts.map +1 -0
- package/dist/content/types.js +10 -0
- package/dist/content/types.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/http-wrapper.d.ts +7 -0
- package/dist/http-wrapper.d.ts.map +1 -1
- package/dist/http-wrapper.js +449 -29
- package/dist/http-wrapper.js.map +1 -1
- package/dist/i18n/en.json +120 -0
- package/dist/i18n/fr.json +120 -0
- package/dist/i18n/index.d.ts +168 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +213 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/library/notebook-library.d.ts +4 -0
- package/dist/library/notebook-library.d.ts.map +1 -1
- package/dist/library/notebook-library.js +20 -3
- package/dist/library/notebook-library.js.map +1 -1
- package/dist/session/browser-session.d.ts +35 -8
- package/dist/session/browser-session.d.ts.map +1 -1
- package/dist/session/browser-session.js +243 -28
- package/dist/session/browser-session.js.map +1 -1
- package/dist/session/session-manager.d.ts +6 -0
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +46 -14
- package/dist/session/session-manager.js.map +1 -1
- package/dist/session/shared-context-manager.d.ts +3 -3
- package/dist/session/shared-context-manager.d.ts.map +1 -1
- package/dist/session/shared-context-manager.js +10 -7
- package/dist/session/shared-context-manager.js.map +1 -1
- package/dist/stdio-http-proxy.d.ts +24 -0
- package/dist/stdio-http-proxy.d.ts.map +1 -0
- package/dist/stdio-http-proxy.js +592 -0
- package/dist/stdio-http-proxy.js.map +1 -0
- package/dist/tools/index.d.ts +106 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1028 -7
- package/dist/tools/index.js.map +1 -1
- package/dist/types.d.ts +81 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/citation-extractor.d.ts +66 -0
- package/dist/utils/citation-extractor.d.ts.map +1 -0
- package/dist/utils/citation-extractor.js +492 -0
- package/dist/utils/citation-extractor.js.map +1 -0
- package/dist/utils/page-utils.d.ts +8 -0
- package/dist/utils/page-utils.d.ts.map +1 -1
- package/dist/utils/page-utils.js +112 -8
- package/dist/utils/page-utils.js.map +1 -1
- package/docs/ADDING_A_LANGUAGE.md +209 -0
- package/docs/ARCHITECTURE_MIGRATION_STUDY.md +894 -0
- package/docs/CHROME_PROFILE_LIMITATION.md +15 -1
- package/docs/MULTI_ACCOUNT_SYSTEM.md +304 -0
- package/package.json +15 -12
- package/scripts/archive/add-and-activate-notebook.ps1 +31 -0
- package/scripts/archive/add-new-notebook.ps1 +25 -0
- package/scripts/archive/add-rom1pey.ps1 +2 -0
- package/scripts/archive/add-rpmonster.ps1 +2 -0
- package/scripts/archive/add-source-debug.ps1 +11 -0
- package/scripts/archive/add-source-e2e.ps1 +28 -0
- package/scripts/archive/add-source-visible.ps1 +11 -0
- package/scripts/archive/add-test-notebook.ps1 +13 -0
- package/scripts/archive/add-test-source.ps1 +50 -0
- package/scripts/archive/capture-screen.ps1 +11 -0
- package/scripts/archive/change-language.mjs +45 -0
- package/scripts/archive/change-language.ts +44 -0
- package/scripts/archive/check-account.ps1 +19 -0
- package/scripts/archive/check-notebook-2.ps1 +8 -0
- package/scripts/archive/check-test-notebook.ps1 +11 -0
- package/scripts/archive/create-notebook-auto.ps1 +31 -0
- package/scripts/archive/create-notebook.ps1 +8 -0
- package/scripts/archive/create-rom1pey-notebook.ps1 +19 -0
- package/scripts/archive/create-rom1pey.ps1 +8 -0
- package/scripts/archive/create-test-notebook-fresh.ps1 +21 -0
- package/scripts/archive/create-test-notebook.ps1 +16 -0
- package/scripts/archive/debug-add-source-auto.ps1 +29 -0
- package/scripts/archive/debug-add-source.ps1 +19 -0
- package/scripts/archive/debug-add-text-source.ps1 +47 -0
- package/scripts/archive/debug-home.ps1 +10 -0
- package/scripts/archive/debug-selectors.ps1 +55 -0
- package/scripts/archive/debug-sources-panel.ps1 +22 -0
- package/scripts/archive/debug-ui.ps1 +17 -0
- package/scripts/archive/discover-home.ps1 +26 -0
- package/scripts/archive/kill-automation-chrome.ps1 +37 -0
- package/scripts/archive/list-my-notebooks.ps1 +27 -0
- package/scripts/archive/navigate-home-visible.ps1 +23 -0
- package/scripts/archive/navigate-home.ps1 +15 -0
- package/scripts/archive/run-e2e-english.ps1 +111 -0
- package/scripts/archive/run-e2e-rom1pey-v2.ps1 +122 -0
- package/scripts/archive/run-e2e-rom1pey.ps1 +117 -0
- package/scripts/archive/setup-english-test.ps1 +36 -0
- package/scripts/archive/setup-test-notebook.ps1 +71 -0
- package/scripts/archive/simple-add-source.ps1 +14 -0
- package/scripts/archive/t10.ps1 +2 -0
- package/scripts/archive/t20.ps1 +4 -0
- package/scripts/archive/t30.ps1 +9 -0
- package/scripts/archive/t31.ps1 +11 -0
- package/scripts/archive/t32.ps1 +6 -0
- package/scripts/archive/t39.ps1 +5 -0
- package/scripts/archive/t40.ps1 +5 -0
- package/scripts/archive/t53.ps1 +12 -0
- package/scripts/archive/t54.ps1 +12 -0
- package/scripts/archive/t55.ps1 +11 -0
- package/scripts/archive/t9.ps1 +1 -0
- package/scripts/archive/test-access.ps1 +28 -0
- package/scripts/archive/test-add-delete-source.ps1 +64 -0
- package/scripts/archive/test-add-source-visible.ps1 +16 -0
- package/scripts/archive/test-add-source.ps1 +19 -0
- package/scripts/archive/test-add-text-debug.ps1 +28 -0
- package/scripts/archive/test-add-text-source.ps1 +8 -0
- package/scripts/archive/test-add-url-source.ps1 +7 -0
- package/scripts/archive/test-ask-ascii.ps1 +20 -0
- package/scripts/archive/test-ask-cnv.ps1 +20 -0
- package/scripts/archive/test-ask-headed.ps1 +51 -0
- package/scripts/archive/test-ask-ifs.ps1 +16 -0
- package/scripts/archive/test-ask-now.ps1 +24 -0
- package/scripts/archive/test-ask-real.ps1 +19 -0
- package/scripts/archive/test-ask-visible.ps1 +20 -0
- package/scripts/archive/test-create-notebook.ps1 +8 -0
- package/scripts/archive/test-create-then-add.ps1 +17 -0
- package/scripts/archive/test-delete-source.ps1 +41 -0
- package/scripts/archive/test-e2e-notebook.ps1 +21 -0
- package/scripts/archive/test-english-notebook.ps1 +20 -0
- package/scripts/archive/test-english.ps1 +7 -0
- package/scripts/archive/test-full-custom-instructions.ps1 +40 -0
- package/scripts/archive/test-full-infographic.ps1 +34 -0
- package/scripts/archive/test-full-language.ps1 +21 -0
- package/scripts/archive/test-full-presentation.ps1 +85 -0
- package/scripts/archive/test-full-report.ps1 +34 -0
- package/scripts/archive/test-full-source-selection.ps1 +35 -0
- package/scripts/archive/test-full-video-brief.ps1 +22 -0
- package/scripts/archive/test-full-video-explainer.ps1 +22 -0
- package/scripts/archive/test-full-video-styles.ps1 +37 -0
- package/scripts/archive/test-generate-report.ps1 +15 -0
- package/scripts/archive/test-generate-study-guide.ps1 +11 -0
- package/scripts/archive/test-headed-ask.ps1 +13 -0
- package/scripts/archive/test-headed-now.ps1 +9 -0
- package/scripts/archive/test-headed.ps1 +9 -0
- package/scripts/archive/test-hello.ps1 +7 -0
- package/scripts/archive/test-i18n-studio.ps1 +8 -0
- package/scripts/archive/test-i18n.ps1 +7 -0
- package/scripts/archive/test-manual-headed.ps1 +26 -0
- package/scripts/archive/test-mathieu-quota.ps1 +8 -0
- package/scripts/archive/test-notebook-1.ps1 +10 -0
- package/scripts/archive/test-notebook-2-sources.ps1 +12 -0
- package/scripts/archive/test-notebook1.ps1 +14 -0
- package/scripts/archive/test-personal-notebook.ps1 +14 -0
- package/scripts/archive/test-rate-limit.ps1 +19 -0
- package/scripts/archive/test-real-ask.ps1 +50 -0
- package/scripts/archive/test-real-ask2.ps1 +30 -0
- package/scripts/archive/test-rom1pey.ps1 +7 -0
- package/scripts/archive/test-rotation-complete.ps1 +14 -0
- package/scripts/archive/test-rotation.ps1 +8 -0
- package/scripts/archive/test-show-browser.ps1 +39 -0
- package/scripts/archive/test-update-notebook.ps1 +4 -0
- package/scripts/archive/verify-language-slow.ps1 +21 -0
- package/scripts/archive/verify-language.ps1 +15 -0
- package/scripts/check-server.ps1 +46 -0
- package/scripts/mcp-wsl-helper.sh +146 -0
- package/scripts/start-server.ps1 +94 -0
- package/scripts/stop-server.ps1 +30 -0
- package/scripts/switch-account-language.sh +191 -0
- package/scripts/test-account.ps1 +58 -0
- package/dist/__tests__/cleanup-manager.test.d.ts +0 -2
- package/dist/__tests__/cleanup-manager.test.d.ts.map +0 -1
- package/dist/__tests__/cleanup-manager.test.js +0 -341
- package/dist/__tests__/cleanup-manager.test.js.map +0 -1
- package/dist/__tests__/config-parsing.test.d.ts +0 -2
- package/dist/__tests__/config-parsing.test.d.ts.map +0 -1
- package/dist/__tests__/config-parsing.test.js +0 -338
- package/dist/__tests__/config-parsing.test.js.map +0 -1
- package/dist/__tests__/config.test.d.ts +0 -2
- package/dist/__tests__/config.test.d.ts.map +0 -1
- package/dist/__tests__/config.test.js +0 -267
- package/dist/__tests__/config.test.js.map +0 -1
- package/dist/__tests__/errors.test.d.ts +0 -2
- package/dist/__tests__/errors.test.d.ts.map +0 -1
- package/dist/__tests__/errors.test.js +0 -166
- package/dist/__tests__/errors.test.js.map +0 -1
- package/dist/__tests__/logger.test.d.ts +0 -2
- package/dist/__tests__/logger.test.d.ts.map +0 -1
- package/dist/__tests__/logger.test.js +0 -324
- package/dist/__tests__/logger.test.js.map +0 -1
- package/dist/__tests__/page-utils.test.d.ts +0 -2
- package/dist/__tests__/page-utils.test.d.ts.map +0 -1
- package/dist/__tests__/page-utils.test.js +0 -349
- package/dist/__tests__/page-utils.test.js.map +0 -1
- package/dist/__tests__/setup-verification.test.d.ts +0 -2
- package/dist/__tests__/setup-verification.test.d.ts.map +0 -1
- package/dist/__tests__/setup-verification.test.js +0 -15
- package/dist/__tests__/setup-verification.test.js.map +0 -1
- package/dist/__tests__/stealth-utils.test.d.ts +0 -2
- package/dist/__tests__/stealth-utils.test.d.ts.map +0 -1
- package/dist/__tests__/stealth-utils.test.js +0 -413
- package/dist/__tests__/stealth-utils.test.js.map +0 -1
- package/dist/__tests__/types.test.d.ts +0 -2
- package/dist/__tests__/types.test.d.ts.map +0 -1
- package/dist/__tests__/types.test.js +0 -461
- package/dist/__tests__/types.test.js.map +0 -1
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Citation Extractor for NotebookLM
|
|
3
|
+
*
|
|
4
|
+
* Extracts source citations by hovering over citation markers [1], [2], etc.
|
|
5
|
+
* and capturing the tooltip content.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Hover-based extraction (no additional API calls)
|
|
9
|
+
* - Multiple output formats (inline, footnotes, json, expanded)
|
|
10
|
+
* - Graceful fallback if citations can't be extracted
|
|
11
|
+
*/
|
|
12
|
+
import { log } from './logger.js';
|
|
13
|
+
import { randomDelay } from './stealth-utils.js';
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// CSS Selectors for NotebookLM Citations
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Selectors to find citation markers in the response
|
|
19
|
+
* NotebookLM typically uses superscript numbers or bracketed references
|
|
20
|
+
*/
|
|
21
|
+
const CITATION_SELECTORS = [
|
|
22
|
+
// Primary: Citation links/buttons
|
|
23
|
+
'.citation-link',
|
|
24
|
+
'.citation-marker',
|
|
25
|
+
'[data-citation]',
|
|
26
|
+
'[data-citation-id]',
|
|
27
|
+
'[data-source-id]',
|
|
28
|
+
// Superscript numbers
|
|
29
|
+
'sup.citation',
|
|
30
|
+
'sup[data-citation]',
|
|
31
|
+
'sup a',
|
|
32
|
+
// Bracketed references [1], [2]
|
|
33
|
+
'.reference-marker',
|
|
34
|
+
'[role="button"][aria-label*="citation"]',
|
|
35
|
+
'[role="button"][aria-label*="source"]',
|
|
36
|
+
// NotebookLM specific (may need adjustment based on actual DOM)
|
|
37
|
+
'.source-citation',
|
|
38
|
+
'.inline-citation',
|
|
39
|
+
'button.citation',
|
|
40
|
+
// Generic clickable citations
|
|
41
|
+
'[class*="citation"]',
|
|
42
|
+
'[class*="source-ref"]',
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Selectors for the tooltip/popover that appears on hover
|
|
46
|
+
*/
|
|
47
|
+
const TOOLTIP_SELECTORS = [
|
|
48
|
+
// Common tooltip patterns
|
|
49
|
+
'[role="tooltip"]',
|
|
50
|
+
'.tooltip',
|
|
51
|
+
'.popover',
|
|
52
|
+
'.citation-tooltip',
|
|
53
|
+
'.citation-popover',
|
|
54
|
+
'.source-preview',
|
|
55
|
+
'.source-tooltip',
|
|
56
|
+
// Material Design / Google patterns
|
|
57
|
+
'.mdc-tooltip',
|
|
58
|
+
'.mat-tooltip',
|
|
59
|
+
'[class*="tooltip"]',
|
|
60
|
+
'[class*="popover"]',
|
|
61
|
+
// NotebookLM specific
|
|
62
|
+
'.citation-preview',
|
|
63
|
+
'.source-card',
|
|
64
|
+
'.source-snippet',
|
|
65
|
+
'[data-tooltip]',
|
|
66
|
+
'[aria-describedby]',
|
|
67
|
+
];
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// Main Extraction Function
|
|
70
|
+
// ============================================================================
|
|
71
|
+
/**
|
|
72
|
+
* Extract citations from a NotebookLM response by hovering over citation markers
|
|
73
|
+
*
|
|
74
|
+
* @param page Playwright page instance
|
|
75
|
+
* @param answerText The answer text to process
|
|
76
|
+
* @param responseContainer The container element holding the response
|
|
77
|
+
* @param format Desired output format
|
|
78
|
+
* @returns Extraction result with formatted answer and citations
|
|
79
|
+
*/
|
|
80
|
+
export async function extractCitations(page, answerText, responseContainer, format = 'none') {
|
|
81
|
+
// Early return if no extraction requested
|
|
82
|
+
if (format === 'none') {
|
|
83
|
+
return {
|
|
84
|
+
originalAnswer: answerText,
|
|
85
|
+
formattedAnswer: answerText,
|
|
86
|
+
citations: [],
|
|
87
|
+
format,
|
|
88
|
+
success: true,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
log.info(`📚 [CITATIONS] Extracting sources (format: ${format})...`);
|
|
92
|
+
const citations = [];
|
|
93
|
+
try {
|
|
94
|
+
// Find citation markers in the response
|
|
95
|
+
const citationElements = await findCitationElements(page, responseContainer);
|
|
96
|
+
if (citationElements.length === 0) {
|
|
97
|
+
log.info(`📚 [CITATIONS] No citation markers found in response`);
|
|
98
|
+
return {
|
|
99
|
+
originalAnswer: answerText,
|
|
100
|
+
formattedAnswer: answerText,
|
|
101
|
+
citations: [],
|
|
102
|
+
format,
|
|
103
|
+
success: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
log.info(`📚 [CITATIONS] Found ${citationElements.length} citation markers`);
|
|
107
|
+
// Extract source text for each citation via hover
|
|
108
|
+
for (const { element, marker, number } of citationElements) {
|
|
109
|
+
try {
|
|
110
|
+
const sourceText = await extractSourceViaHover(page, element);
|
|
111
|
+
if (sourceText) {
|
|
112
|
+
citations.push({
|
|
113
|
+
marker,
|
|
114
|
+
number,
|
|
115
|
+
sourceText,
|
|
116
|
+
});
|
|
117
|
+
log.success(` ✅ [${marker}] Extracted: "${sourceText.substring(0, 50)}..."`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
log.warning(` ⚠️ [${marker}] Could not extract source text`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
log.warning(` ⚠️ [${marker}] Error extracting: ${error}`);
|
|
125
|
+
}
|
|
126
|
+
// Small delay between hovers to avoid detection
|
|
127
|
+
await randomDelay(100, 200);
|
|
128
|
+
}
|
|
129
|
+
// Format the answer based on requested format
|
|
130
|
+
const formattedAnswer = formatAnswerWithSources(answerText, citations, format);
|
|
131
|
+
log.success(`📚 [CITATIONS] Extracted ${citations.length}/${citationElements.length} sources`);
|
|
132
|
+
return {
|
|
133
|
+
originalAnswer: answerText,
|
|
134
|
+
formattedAnswer,
|
|
135
|
+
citations,
|
|
136
|
+
format,
|
|
137
|
+
success: true,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
142
|
+
log.error(`❌ [CITATIONS] Extraction failed: ${errorMessage}`);
|
|
143
|
+
return {
|
|
144
|
+
originalAnswer: answerText,
|
|
145
|
+
formattedAnswer: answerText,
|
|
146
|
+
citations: [],
|
|
147
|
+
format,
|
|
148
|
+
success: false,
|
|
149
|
+
error: errorMessage,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Find citation marker elements in the response
|
|
155
|
+
*/
|
|
156
|
+
async function findCitationElements(page, container) {
|
|
157
|
+
const results = [];
|
|
158
|
+
const seenNumbers = new Set();
|
|
159
|
+
// Search context: container if available, otherwise full page
|
|
160
|
+
const searchContext = container || page;
|
|
161
|
+
// Try each selector
|
|
162
|
+
for (const selector of CITATION_SELECTORS) {
|
|
163
|
+
try {
|
|
164
|
+
const elements = await searchContext.$$(selector);
|
|
165
|
+
for (const element of elements) {
|
|
166
|
+
try {
|
|
167
|
+
// Get the text content to identify the citation number
|
|
168
|
+
const text = await element.innerText();
|
|
169
|
+
const match = text.match(/\[?(\d+)\]?/);
|
|
170
|
+
if (match) {
|
|
171
|
+
const number = parseInt(match[1], 10);
|
|
172
|
+
// Skip if we've already found this citation
|
|
173
|
+
if (seenNumbers.has(number))
|
|
174
|
+
continue;
|
|
175
|
+
seenNumbers.add(number);
|
|
176
|
+
const marker = `[${number}]`;
|
|
177
|
+
results.push({ element, marker, number });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Also try to find citations by regex pattern in the page
|
|
190
|
+
if (results.length === 0) {
|
|
191
|
+
const regexResults = await findCitationsByRegex(page, container);
|
|
192
|
+
results.push(...regexResults);
|
|
193
|
+
}
|
|
194
|
+
// Sort by citation number
|
|
195
|
+
results.sort((a, b) => a.number - b.number);
|
|
196
|
+
return results;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Find citations using regex matching on text content
|
|
200
|
+
* Fallback method when CSS selectors don't work
|
|
201
|
+
*
|
|
202
|
+
* This improved version:
|
|
203
|
+
* 1. Detects citation markers [n] in the text
|
|
204
|
+
* 2. Finds clickable elements containing those markers
|
|
205
|
+
* 3. Returns element handles for hover extraction
|
|
206
|
+
*/
|
|
207
|
+
async function findCitationsByRegex(page, container) {
|
|
208
|
+
const results = [];
|
|
209
|
+
const seenNumbers = new Set();
|
|
210
|
+
try {
|
|
211
|
+
// First, detect unique citation numbers in the response text
|
|
212
|
+
const citationNumbers = await page.evaluate((containerSelector) => {
|
|
213
|
+
const searchRoot = containerSelector
|
|
214
|
+
? // @ts-expect-error - document available in browser context
|
|
215
|
+
document.querySelector(containerSelector)
|
|
216
|
+
: // @ts-expect-error - document available in browser context
|
|
217
|
+
document.body;
|
|
218
|
+
if (!searchRoot)
|
|
219
|
+
return [];
|
|
220
|
+
const text = searchRoot.textContent || '';
|
|
221
|
+
const matches = text.matchAll(/\[(\d+)\]/g);
|
|
222
|
+
const numbers = new Set();
|
|
223
|
+
for (const match of matches) {
|
|
224
|
+
numbers.add(parseInt(match[1], 10));
|
|
225
|
+
}
|
|
226
|
+
return Array.from(numbers).sort((a, b) => a - b);
|
|
227
|
+
}, container ? '.to-user-container .message-text-content' : null);
|
|
228
|
+
log.info(`📚 [CITATIONS] Regex found ${citationNumbers.length} unique citation markers: [${citationNumbers.join(', ')}]`);
|
|
229
|
+
// For each citation number, try to find a clickable element
|
|
230
|
+
// NotebookLM typically wraps citations in <a>, <button>, or <span> with click handlers
|
|
231
|
+
const searchContext = container || page;
|
|
232
|
+
for (const num of citationNumbers) {
|
|
233
|
+
if (seenNumbers.has(num))
|
|
234
|
+
continue;
|
|
235
|
+
// Try multiple strategies to find the citation element
|
|
236
|
+
const strategies = [
|
|
237
|
+
// Strategy 1: Look for links with the citation number
|
|
238
|
+
`a:has-text("[${num}]")`,
|
|
239
|
+
`button:has-text("[${num}]")`,
|
|
240
|
+
`span:has-text("[${num}]")`,
|
|
241
|
+
// Strategy 2: Look for elements with citation-related attributes
|
|
242
|
+
`[data-citation="${num}"]`,
|
|
243
|
+
`[data-source="${num}"]`,
|
|
244
|
+
`[aria-label*="${num}"]`,
|
|
245
|
+
// Strategy 3: Look for superscript elements
|
|
246
|
+
`sup:has-text("${num}")`,
|
|
247
|
+
// Strategy 4: Generic clickable elements with the number
|
|
248
|
+
`[role="button"]:has-text("[${num}]")`,
|
|
249
|
+
`[role="link"]:has-text("[${num}]")`,
|
|
250
|
+
];
|
|
251
|
+
for (const selector of strategies) {
|
|
252
|
+
try {
|
|
253
|
+
const element = await searchContext.$(selector);
|
|
254
|
+
if (element) {
|
|
255
|
+
const isVisible = await element.isVisible();
|
|
256
|
+
if (isVisible) {
|
|
257
|
+
seenNumbers.add(num);
|
|
258
|
+
results.push({
|
|
259
|
+
element,
|
|
260
|
+
marker: `[${num}]`,
|
|
261
|
+
number: num,
|
|
262
|
+
});
|
|
263
|
+
log.info(` 📌 Found element for [${num}] using selector: ${selector}`);
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// If no element found with specific selectors, try XPath as last resort
|
|
273
|
+
if (!seenNumbers.has(num)) {
|
|
274
|
+
try {
|
|
275
|
+
// Find any element that contains exactly [n]
|
|
276
|
+
const xpath = `//*[contains(text(), '[${num}]')]`;
|
|
277
|
+
const elements = await page.$$(`::-p-xpath(${xpath})`);
|
|
278
|
+
for (const element of elements) {
|
|
279
|
+
try {
|
|
280
|
+
const text = await element.innerText();
|
|
281
|
+
// Make sure it's the citation marker, not just any text with [n]
|
|
282
|
+
if (text.includes(`[${num}]`) && text.length < 50) {
|
|
283
|
+
const isVisible = await element.isVisible();
|
|
284
|
+
if (isVisible) {
|
|
285
|
+
seenNumbers.add(num);
|
|
286
|
+
results.push({
|
|
287
|
+
element,
|
|
288
|
+
marker: `[${num}]`,
|
|
289
|
+
number: num,
|
|
290
|
+
});
|
|
291
|
+
log.info(` 📌 Found element for [${num}] using XPath fallback`);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// XPath failed, continue without this citation
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (!seenNumbers.has(num)) {
|
|
306
|
+
log.warning(` ⚠️ Could not find DOM element for [${num}]`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
log.info(`📚 [CITATIONS] Found ${results.length}/${citationNumbers.length} citation elements`);
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
log.warning(`⚠️ [CITATIONS] Regex search failed: ${error}`);
|
|
313
|
+
}
|
|
314
|
+
// Sort by citation number
|
|
315
|
+
results.sort((a, b) => a.number - b.number);
|
|
316
|
+
return results;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Extract source text by hovering over a citation element
|
|
320
|
+
*/
|
|
321
|
+
async function extractSourceViaHover(page, element) {
|
|
322
|
+
try {
|
|
323
|
+
// Scroll element into view
|
|
324
|
+
await element.scrollIntoViewIfNeeded();
|
|
325
|
+
await randomDelay(50, 100);
|
|
326
|
+
// Hover over the element
|
|
327
|
+
await element.hover();
|
|
328
|
+
// Wait for tooltip to appear
|
|
329
|
+
await randomDelay(300, 500);
|
|
330
|
+
// Try to find and read the tooltip content
|
|
331
|
+
for (const tooltipSelector of TOOLTIP_SELECTORS) {
|
|
332
|
+
try {
|
|
333
|
+
const tooltip = await page.$(tooltipSelector);
|
|
334
|
+
if (tooltip) {
|
|
335
|
+
const isVisible = await tooltip.isVisible();
|
|
336
|
+
if (isVisible) {
|
|
337
|
+
const text = await tooltip.innerText();
|
|
338
|
+
if (text && text.trim()) {
|
|
339
|
+
// Move mouse away to dismiss tooltip
|
|
340
|
+
await page.mouse.move(0, 0);
|
|
341
|
+
await randomDelay(100, 150);
|
|
342
|
+
return text.trim();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Fallback: Check for aria-describedby attribute
|
|
352
|
+
try {
|
|
353
|
+
const describedBy = await element.getAttribute('aria-describedby');
|
|
354
|
+
if (describedBy) {
|
|
355
|
+
const tooltipById = await page.$(`#${describedBy}`);
|
|
356
|
+
if (tooltipById) {
|
|
357
|
+
const text = await tooltipById.innerText();
|
|
358
|
+
if (text && text.trim()) {
|
|
359
|
+
await page.mouse.move(0, 0);
|
|
360
|
+
return text.trim();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// Ignore
|
|
367
|
+
}
|
|
368
|
+
// Move mouse away even if we didn't find content
|
|
369
|
+
await page.mouse.move(0, 0);
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
log.warning(`⚠️ [CITATIONS] Hover extraction failed: ${error}`);
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// ============================================================================
|
|
378
|
+
// Formatting Functions
|
|
379
|
+
// ============================================================================
|
|
380
|
+
/**
|
|
381
|
+
* Format the answer with extracted sources based on requested format
|
|
382
|
+
*/
|
|
383
|
+
export function formatAnswerWithSources(answer, citations, format) {
|
|
384
|
+
if (citations.length === 0 || format === 'none') {
|
|
385
|
+
return answer;
|
|
386
|
+
}
|
|
387
|
+
switch (format) {
|
|
388
|
+
case 'inline':
|
|
389
|
+
return formatInline(answer, citations);
|
|
390
|
+
case 'footnotes':
|
|
391
|
+
return formatFootnotes(answer, citations);
|
|
392
|
+
case 'expanded':
|
|
393
|
+
return formatExpanded(answer, citations);
|
|
394
|
+
case 'json':
|
|
395
|
+
// For JSON format, we return the original answer
|
|
396
|
+
// The citations are available in the result object
|
|
397
|
+
return answer;
|
|
398
|
+
default:
|
|
399
|
+
return answer;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Format with inline source excerpts: "text [1: source excerpt]"
|
|
404
|
+
*
|
|
405
|
+
* NotebookLM returns citations in different formats:
|
|
406
|
+
* - Superscript numbers without brackets: "text1,2" or "text3"
|
|
407
|
+
* - Sometimes with brackets: "text[1]"
|
|
408
|
+
* - Sometimes stuck together: "text123" (meaning citations 1, 2, 3)
|
|
409
|
+
*
|
|
410
|
+
* This function handles all formats.
|
|
411
|
+
*/
|
|
412
|
+
function formatInline(answer, citations) {
|
|
413
|
+
let result = answer;
|
|
414
|
+
// Sort citations by number in DESCENDING order to avoid replacing [1] before [10]
|
|
415
|
+
const sortedCitations = [...citations].sort((a, b) => b.number - a.number);
|
|
416
|
+
for (const citation of sortedCitations) {
|
|
417
|
+
const shortSource = truncateSource(citation.sourceText, 100);
|
|
418
|
+
const num = citation.number;
|
|
419
|
+
const inlineReplacement = `[${num}: "${shortSource}"]`;
|
|
420
|
+
// Pattern 1: Bracketed format [n]
|
|
421
|
+
const bracketedPattern = `\\[${num}\\]`;
|
|
422
|
+
if (new RegExp(bracketedPattern).test(result)) {
|
|
423
|
+
result = result.replace(new RegExp(bracketedPattern, 'g'), inlineReplacement);
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
// Pattern 2: Superscript format - number followed by comma/period/space/newline/end
|
|
427
|
+
// Also handles citations stuck together by using lookahead for next digit or punctuation
|
|
428
|
+
// Match: "word1," or "word1." or "word12" (where we want to match the 1)
|
|
429
|
+
const superscriptPattern = `(\\D)(${num})(?=[,\\.;:\\s\\n]|(?=\\d)|$)`;
|
|
430
|
+
if (new RegExp(superscriptPattern).test(result)) {
|
|
431
|
+
result = result.replace(new RegExp(superscriptPattern, 'g'), `$1${inlineReplacement}`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Format with footnotes at the end
|
|
438
|
+
*/
|
|
439
|
+
function formatFootnotes(answer, citations) {
|
|
440
|
+
if (citations.length === 0)
|
|
441
|
+
return answer;
|
|
442
|
+
const footnotes = citations
|
|
443
|
+
.map((c) => {
|
|
444
|
+
const source = c.sourceName ? `${c.sourceName}: ` : '';
|
|
445
|
+
return `${c.marker} ${source}${c.sourceText}`;
|
|
446
|
+
})
|
|
447
|
+
.join('\n\n');
|
|
448
|
+
return `${answer}\n\n---\n**Sources:**\n${footnotes}`;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Format with expanded inline quotes replacing markers
|
|
452
|
+
*
|
|
453
|
+
* Handles bracketed [n], superscript n, and stuck-together formats.
|
|
454
|
+
*/
|
|
455
|
+
function formatExpanded(answer, citations) {
|
|
456
|
+
let result = answer;
|
|
457
|
+
// Sort citations by number in DESCENDING order to avoid replacing 1 before 10
|
|
458
|
+
const sortedCitations = [...citations].sort((a, b) => b.number - a.number);
|
|
459
|
+
for (const citation of sortedCitations) {
|
|
460
|
+
const shortSource = truncateSource(citation.sourceText, 150);
|
|
461
|
+
const replacement = `"${shortSource}"`;
|
|
462
|
+
const num = citation.number;
|
|
463
|
+
// Pattern 1: Bracketed format [n]
|
|
464
|
+
const bracketedPattern = `\\[${num}\\]`;
|
|
465
|
+
if (new RegExp(bracketedPattern).test(result)) {
|
|
466
|
+
result = result.replace(new RegExp(bracketedPattern, 'g'), replacement);
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
// Pattern 2: Superscript format - also handles stuck-together citations
|
|
470
|
+
const superscriptPattern = `(\\D)(${num})(?=[,\\.;:\\s\\n]|(?=\\d)|$)`;
|
|
471
|
+
if (new RegExp(superscriptPattern).test(result)) {
|
|
472
|
+
result = result.replace(new RegExp(superscriptPattern, 'g'), `$1${replacement}`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return result;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Truncate source text to a reasonable length
|
|
479
|
+
*/
|
|
480
|
+
function truncateSource(text, maxLength) {
|
|
481
|
+
if (text.length <= maxLength)
|
|
482
|
+
return text;
|
|
483
|
+
return text.substring(0, maxLength - 3) + '...';
|
|
484
|
+
}
|
|
485
|
+
// ============================================================================
|
|
486
|
+
// Exports
|
|
487
|
+
// ============================================================================
|
|
488
|
+
export default {
|
|
489
|
+
extractCitations,
|
|
490
|
+
formatAnswerWithSources,
|
|
491
|
+
};
|
|
492
|
+
//# sourceMappingURL=citation-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation-extractor.js","sourceRoot":"","sources":["../../src/utils/citation-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
* Based on the Python implementation from page_utils.py
|
|
11
11
|
*/
|
|
12
12
|
import type { Page } from 'patchright';
|
|
13
|
+
/**
|
|
14
|
+
* Check if text is an error message from NotebookLM
|
|
15
|
+
*/
|
|
16
|
+
export declare function isErrorMessage(text: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if text indicates a rate limit error (should trigger account rotation)
|
|
19
|
+
*/
|
|
20
|
+
export declare function isRateLimitMessage(text: string): boolean;
|
|
13
21
|
/**
|
|
14
22
|
* Snapshot the latest response text currently visible
|
|
15
23
|
* Returns null if no response found
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-utils.d.ts","sourceRoot":"","sources":["../../src/utils/page-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"page-utils.d.ts","sourceRoot":"","sources":["../../src/utils/page-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAkFvC;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGxD;AA4CD;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE/E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BxE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,GACL,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA8IxB;;;;;;;AA+MD,wBAKE"}
|