orbitx 0.0.3 → 0.0.4
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/{src/core/ai-provider.ts → dist/core/ai-provider.d.ts} +19 -25
- package/dist/core/ai-provider.d.ts.map +1 -0
- package/dist/core/ai-provider.js +4 -0
- package/dist/core/ai-provider.js.map +1 -0
- package/dist/core/base-agent.d.ts +53 -0
- package/dist/core/base-agent.d.ts.map +1 -0
- package/{src/core/base-agent.ts → dist/core/base-agent.js} +197 -269
- package/dist/core/base-agent.js.map +1 -0
- package/dist/core/deepseek-provider.d.ts +9 -0
- package/dist/core/deepseek-provider.d.ts.map +1 -0
- package/{src/core/deepseek-provider.ts → dist/core/deepseek-provider.js} +60 -71
- package/dist/core/deepseek-provider.js.map +1 -0
- package/dist/core/mcp-client.d.ts +21 -0
- package/dist/core/mcp-client.d.ts.map +1 -0
- package/{src/core/mcp-client.ts → dist/core/mcp-client.js} +90 -113
- package/dist/core/mcp-client.js.map +1 -0
- package/dist/core/mcp-computer.d.ts +4 -0
- package/dist/core/mcp-computer.d.ts.map +1 -0
- package/{src/core/mcp-computer.ts → dist/core/mcp-computer.js} +5 -5
- package/dist/core/mcp-computer.js.map +1 -0
- package/dist/core/mcp-connection.d.ts +6 -0
- package/dist/core/mcp-connection.d.ts.map +1 -0
- package/dist/core/mcp-connection.js +10 -0
- package/dist/core/mcp-connection.js.map +1 -0
- package/dist/core/mcp-ipc-connection.d.ts +20 -0
- package/dist/core/mcp-ipc-connection.d.ts.map +1 -0
- package/{src/core/mcp-ipc-connection.ts → dist/core/mcp-ipc-connection.js} +126 -153
- package/dist/core/mcp-ipc-connection.js.map +1 -0
- package/dist/core/mcp-server.d.ts +9 -0
- package/dist/core/mcp-server.d.ts.map +1 -0
- package/{src/core/mcp-server.ts → dist/core/mcp-server.js} +45 -49
- package/dist/core/mcp-server.js.map +1 -0
- package/dist/core/mcp.d.ts +29 -0
- package/dist/core/mcp.d.ts.map +1 -0
- package/dist/core/mcp.js +11 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/ollama-provider.d.ts +9 -0
- package/dist/core/ollama-provider.d.ts.map +1 -0
- package/{src/core/ollama-provider.ts → dist/core/ollama-provider.js} +59 -70
- package/dist/core/ollama-provider.js.map +1 -0
- package/dist/core/skill.d.ts +15 -0
- package/dist/core/skill.d.ts.map +1 -0
- package/dist/core/skill.js +11 -0
- package/dist/core/skill.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/{src/index.ts → dist/index.js} +16 -17
- package/dist/index.js.map +1 -0
- package/dist/templates/researcher.d.ts +27 -0
- package/dist/templates/researcher.d.ts.map +1 -0
- package/dist/templates/researcher.js +70 -0
- package/dist/templates/researcher.js.map +1 -0
- package/dist/templates/simple.d.ts +27 -0
- package/dist/templates/simple.d.ts.map +1 -0
- package/dist/templates/simple.js +35 -0
- package/dist/templates/simple.js.map +1 -0
- package/dist/tests/mcp.test.d.ts +2 -0
- package/dist/tests/mcp.test.d.ts.map +1 -0
- package/{src/tests/mcp.test.ts → dist/tests/mcp.test.js} +55 -73
- package/dist/tests/mcp.test.js.map +1 -0
- package/dist/tools/fs/index.d.ts +3 -0
- package/dist/tools/fs/index.d.ts.map +1 -0
- package/dist/tools/fs/index.js +3 -0
- package/dist/tools/fs/index.js.map +1 -0
- package/dist/tools/fs/read-file.d.ts +4 -0
- package/dist/tools/fs/read-file.d.ts.map +1 -0
- package/{src/tools/fs/read-file.ts → dist/tools/fs/read-file.js} +49 -54
- package/dist/tools/fs/read-file.js.map +1 -0
- package/dist/tools/fs/write-file.d.ts +4 -0
- package/dist/tools/fs/write-file.d.ts.map +1 -0
- package/{src/tools/fs/write-file.ts → dist/tools/fs/write-file.js} +68 -73
- package/dist/tools/fs/write-file.js.map +1 -0
- package/dist/tools/utils/get-current-time.d.ts +4 -0
- package/dist/tools/utils/get-current-time.d.ts.map +1 -0
- package/{src/tools/utils/get-current-time.ts → dist/tools/utils/get-current-time.js} +40 -45
- package/dist/tools/utils/get-current-time.js.map +1 -0
- package/dist/tools/utils/index.d.ts +2 -0
- package/dist/tools/utils/index.d.ts.map +1 -0
- package/dist/tools/utils/index.js +2 -0
- package/dist/tools/utils/index.js.map +1 -0
- package/dist/tools/www/fetch.d.ts +4 -0
- package/dist/tools/www/fetch.d.ts.map +1 -0
- package/{src/tools/www/fetch.ts → dist/tools/www/fetch.js} +147 -161
- package/dist/tools/www/fetch.js.map +1 -0
- package/dist/tools/www/index.d.ts +4 -0
- package/dist/tools/www/index.d.ts.map +1 -0
- package/dist/tools/www/index.js +4 -0
- package/dist/tools/www/index.js.map +1 -0
- package/dist/tools/www/read-web-page.d.ts +4 -0
- package/dist/tools/www/read-web-page.d.ts.map +1 -0
- package/{src/tools/www/read-web-page.ts → dist/tools/www/read-web-page.js} +330 -350
- package/dist/tools/www/read-web-page.js.map +1 -0
- package/dist/tools/www/web-search.d.ts +4 -0
- package/dist/tools/www/web-search.d.ts.map +1 -0
- package/{src/tools/www/web-search.ts → dist/tools/www/web-search.js} +82 -102
- package/dist/tools/www/web-search.js.map +1 -0
- package/package.json +19 -5
- package/.env.example +0 -1
- package/orbitx.png +0 -0
- package/public/index.html +0 -397
- package/src/core/mcp-connection.ts +0 -12
- package/src/core/mcp.ts +0 -23
- package/src/core/skill.ts +0 -16
- package/src/templates/researcher.ts +0 -73
- package/src/templates/simple.ts +0 -64
- package/src/tools/fs/index.ts +0 -2
- package/src/tools/utils/index.ts +0 -1
- package/src/tools/www/index.ts +0 -3
- package/tsconfig.json +0 -34
|
@@ -1,350 +1,330 @@
|
|
|
1
|
-
import puppeteer, { Browser } from "puppeteer-core";
|
|
2
|
-
import os from "os";
|
|
3
|
-
import MCPTool from "../../core/mcp";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (!
|
|
32
|
-
throw new Error("Invalid
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
await page.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
".
|
|
76
|
-
".
|
|
77
|
-
".
|
|
78
|
-
".
|
|
79
|
-
".
|
|
80
|
-
".
|
|
81
|
-
".
|
|
82
|
-
".
|
|
83
|
-
".
|
|
84
|
-
".
|
|
85
|
-
".
|
|
86
|
-
".
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
document.querySelector("
|
|
125
|
-
document.querySelector("
|
|
126
|
-
document.querySelector("
|
|
127
|
-
document.querySelector(".main
|
|
128
|
-
document.querySelector(".content"),
|
|
129
|
-
document.querySelector(".
|
|
130
|
-
document.querySelector(".
|
|
131
|
-
document.querySelector("
|
|
132
|
-
document.querySelector(".post"),
|
|
133
|
-
document.querySelector(".entry"),
|
|
134
|
-
document.querySelector(".article-
|
|
135
|
-
document.querySelector(".
|
|
136
|
-
document.querySelector(".
|
|
137
|
-
document.querySelector(".
|
|
138
|
-
document.querySelector(".
|
|
139
|
-
document.querySelector(".
|
|
140
|
-
document.querySelector(".
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
document.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (
|
|
198
|
-
return (
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (tag === "
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
.
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if (!output) {
|
|
333
|
-
throw new Error(`Failed to fetch content from ${url} - received empty response`);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
return {
|
|
337
|
-
content: output,
|
|
338
|
-
size: output.length
|
|
339
|
-
};
|
|
340
|
-
} catch (error) {
|
|
341
|
-
return {
|
|
342
|
-
error: error instanceof Error ? error.message : String(error),
|
|
343
|
-
};
|
|
344
|
-
} finally {
|
|
345
|
-
await browser?.close();
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
export default ReadWebPageTool;
|
|
1
|
+
import puppeteer, { Browser } from "puppeteer-core";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import MCPTool from "../../core/mcp";
|
|
4
|
+
export const ReadWebPageTool = new MCPTool({
|
|
5
|
+
name: "read-web-page",
|
|
6
|
+
description: "Retrieve and extract content from a specific URL. Use this when you need to read a webpage's HTML or convert it to clean markdown text. Ideal for reading articles, documentation, API responses, or any web content. Returns structured text without navigation menus or scripts.",
|
|
7
|
+
inputs: [{
|
|
8
|
+
name: "url",
|
|
9
|
+
type: "string",
|
|
10
|
+
description: `Complete URL including protocol (http:// or https://). Example: "https://example.com/page"`,
|
|
11
|
+
required: true,
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: "outputType",
|
|
15
|
+
type: "string",
|
|
16
|
+
description: `Output format: "text" returns clean markdown-formatted content without HTML tags (best for reading articles and text), "html" returns raw HTML source (use for debugging or when structure matters)`,
|
|
17
|
+
required: true,
|
|
18
|
+
}],
|
|
19
|
+
execute: async (_, inputs) => {
|
|
20
|
+
let browser;
|
|
21
|
+
try {
|
|
22
|
+
const url = inputs.url;
|
|
23
|
+
const outputType = inputs.outputType;
|
|
24
|
+
const maxWords = 5000;
|
|
25
|
+
if (!url || typeof url !== "string") {
|
|
26
|
+
throw new Error("Invalid parameter: 'url' must be a non-empty string like 'https://example.com'");
|
|
27
|
+
}
|
|
28
|
+
if (!url.match(/^https?:\/\//i)) {
|
|
29
|
+
throw new Error("Invalid URL format: URL must start with http:// or https://");
|
|
30
|
+
}
|
|
31
|
+
if (!outputType || typeof outputType !== "string") {
|
|
32
|
+
throw new Error("Invalid parameter: 'outputType' must be specified as either 'text' or 'html'");
|
|
33
|
+
}
|
|
34
|
+
if (outputType !== "text" && outputType !== "html") {
|
|
35
|
+
throw new Error(`Invalid outputType '${outputType}': must be 'text' or 'html'`);
|
|
36
|
+
}
|
|
37
|
+
browser = await puppeteer.launch({
|
|
38
|
+
executablePath: process.env.CHROME_PATH || (os.platform() == "win32" ?
|
|
39
|
+
"C:/Program Files/Google/Chrome/Application/chrome.exe" :
|
|
40
|
+
"/usr/bin/google-chrome-stable"),
|
|
41
|
+
headless: false,
|
|
42
|
+
args: ["--no-sandbox"],
|
|
43
|
+
});
|
|
44
|
+
const page = await browser.newPage();
|
|
45
|
+
await page.evaluateOnNewDocument(() => {
|
|
46
|
+
window.__name = (fn, _name) => fn;
|
|
47
|
+
});
|
|
48
|
+
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");
|
|
49
|
+
await page.goto(url, { waitUntil: "networkidle0", timeout: 50000 });
|
|
50
|
+
if (outputType === "html") {
|
|
51
|
+
return await page.content();
|
|
52
|
+
}
|
|
53
|
+
const extracted = await page.evaluate(() => {
|
|
54
|
+
const getInnerText = (el) => {
|
|
55
|
+
if (el instanceof HTMLElement)
|
|
56
|
+
return el.innerText.trim();
|
|
57
|
+
return el.textContent?.trim() || "";
|
|
58
|
+
};
|
|
59
|
+
const garbageSelectors = [
|
|
60
|
+
"script", "style", "noscript", "iframe", "svg", "canvas",
|
|
61
|
+
"nav", "footer", "header", "aside",
|
|
62
|
+
".sidebar", ".toc", ".menu", ".navigation", ".breadcrumb",
|
|
63
|
+
".advertisement", ".ads", ".popup", ".modal",
|
|
64
|
+
".feedback", ".rating", ".comment", ".social-share", ".share",
|
|
65
|
+
".social", ".related", ".recommended", ".popular", ".trending",
|
|
66
|
+
".footer-links", ".copyright", ".privacy", ".terms", ".cookie",
|
|
67
|
+
".consent", ".newsletter", ".subscribe", ".email-signup",
|
|
68
|
+
".download", ".app-promo", ".widget", ".right-rail", ".left-rail",
|
|
69
|
+
".sticky", ".floating", ".popover", ".tooltip", ".dropdown-menu",
|
|
70
|
+
".search", ".filter", ".sort", ".pagination", ".author-bio",
|
|
71
|
+
".meta", ".timestamp", ".category", ".tags", ".breadcrumb",
|
|
72
|
+
".video-player", ".audio-player", ".slider", ".carousel", ".tabs",
|
|
73
|
+
".accordion", ".collapse", ".toggle", ".share-buttons", ".print",
|
|
74
|
+
".pdf", ".download-link", ".external-link", ".like", ".vote",
|
|
75
|
+
".rating-stars", ".review", ".testimonial", ".footnote",
|
|
76
|
+
".reference", ".citation", ".table-of-contents", ".summary",
|
|
77
|
+
".abstract", ".excerpt", ".teaser", ".preview", ".thumbnail",
|
|
78
|
+
".avatar", ".profile", ".user", ".comment-author", ".comment-content",
|
|
79
|
+
".reply", ".thread", ".discussion", ".forum", ".chat-message",
|
|
80
|
+
".notification", ".alert", ".warning", ".error", ".success", ".info",
|
|
81
|
+
".banner", ".hero", ".jumbotron", ".cta", ".call-to-action",
|
|
82
|
+
".button-wrapper", ".btn-group", ".toolbar", ".controls",
|
|
83
|
+
".settings", ".preferences", ".language-selector", ".back-to-top",
|
|
84
|
+
".scroll-to-top", ".share-this", ".bookmark", ".favorite",
|
|
85
|
+
".poll", ".survey", ".quiz", ".load-more", ".infinite-scroll",
|
|
86
|
+
".spinner", ".loader", ".progress", ".visually-hidden", ".sr-only",
|
|
87
|
+
"[role='navigation']", "[role='banner']", "[role='complementary']",
|
|
88
|
+
"[aria-hidden='true']", ".ask-bloom", ".chat-widget", ".support-widget"
|
|
89
|
+
];
|
|
90
|
+
garbageSelectors.forEach(sel => {
|
|
91
|
+
document.querySelectorAll(sel).forEach(el => el.remove());
|
|
92
|
+
});
|
|
93
|
+
document.querySelectorAll("div, section, article").forEach(el => {
|
|
94
|
+
if (!(el instanceof HTMLElement))
|
|
95
|
+
return;
|
|
96
|
+
const text = el.innerText.trim();
|
|
97
|
+
if (!text.length)
|
|
98
|
+
return;
|
|
99
|
+
const links = el.querySelectorAll("a");
|
|
100
|
+
let linkTextLength = 0;
|
|
101
|
+
links.forEach(link => {
|
|
102
|
+
if (link instanceof HTMLElement)
|
|
103
|
+
linkTextLength += link.innerText.length;
|
|
104
|
+
});
|
|
105
|
+
if (linkTextLength / text.length > 0.7) {
|
|
106
|
+
el.remove();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
let mainContent = null;
|
|
110
|
+
const candidates = [
|
|
111
|
+
document.querySelector("main"),
|
|
112
|
+
document.querySelector("article"),
|
|
113
|
+
document.querySelector("[role='main']"),
|
|
114
|
+
document.querySelector(".main-content"),
|
|
115
|
+
document.querySelector(".content"),
|
|
116
|
+
document.querySelector(".post-content"),
|
|
117
|
+
document.querySelector(".prose"),
|
|
118
|
+
document.querySelector("#content"),
|
|
119
|
+
document.querySelector(".post"),
|
|
120
|
+
document.querySelector(".entry"),
|
|
121
|
+
document.querySelector(".article-content"),
|
|
122
|
+
document.querySelector(".story"),
|
|
123
|
+
document.querySelector(".body"),
|
|
124
|
+
document.querySelector(".primary"),
|
|
125
|
+
document.querySelector(".main"),
|
|
126
|
+
document.querySelector(".column-main"),
|
|
127
|
+
document.querySelector(".region-main"),
|
|
128
|
+
document.querySelector(".node-content"),
|
|
129
|
+
document.querySelector(".field-name-body"),
|
|
130
|
+
document.querySelector(".body-field"),
|
|
131
|
+
document.querySelector(".page-content"),
|
|
132
|
+
document.querySelector(".post-body"),
|
|
133
|
+
document.querySelector(".entry-content"),
|
|
134
|
+
document.querySelector(".article-body"),
|
|
135
|
+
document.querySelector(".blog-post"),
|
|
136
|
+
document.querySelector(".single-post"),
|
|
137
|
+
document.querySelector(".main-text"),
|
|
138
|
+
document.querySelector(".primary-content"),
|
|
139
|
+
document.querySelector(".content-area"),
|
|
140
|
+
document.querySelector(".site-content"),
|
|
141
|
+
];
|
|
142
|
+
for (const candidate of candidates) {
|
|
143
|
+
if (candidate && getInnerText(candidate).length > 300) {
|
|
144
|
+
mainContent = candidate;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (!mainContent) {
|
|
149
|
+
let maxTextLen = 0;
|
|
150
|
+
let bestEl = null;
|
|
151
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
|
|
152
|
+
acceptNode: (node) => {
|
|
153
|
+
const el = node;
|
|
154
|
+
const tag = el.tagName.toLowerCase();
|
|
155
|
+
if (["div", "section", "article", "main"].includes(tag)) {
|
|
156
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
157
|
+
}
|
|
158
|
+
return NodeFilter.FILTER_SKIP;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
while (walker.nextNode()) {
|
|
162
|
+
const el = walker.currentNode;
|
|
163
|
+
const textLen = getInnerText(el).length;
|
|
164
|
+
if (textLen > maxTextLen && textLen > 500) {
|
|
165
|
+
maxTextLen = textLen;
|
|
166
|
+
bestEl = el;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
mainContent = bestEl;
|
|
170
|
+
}
|
|
171
|
+
if (!mainContent) {
|
|
172
|
+
mainContent = document.body;
|
|
173
|
+
document.querySelectorAll("aside, .sidebar, nav, footer, header").forEach(el => el.remove());
|
|
174
|
+
}
|
|
175
|
+
function nodeToMd(node, depth = 0) {
|
|
176
|
+
if (node.nodeType === 3) {
|
|
177
|
+
return (node.textContent || "").replace(/\s+/g, " ");
|
|
178
|
+
}
|
|
179
|
+
if (node.nodeType !== 1)
|
|
180
|
+
return "";
|
|
181
|
+
const el = node;
|
|
182
|
+
const tag = el.tagName.toLowerCase();
|
|
183
|
+
if (el instanceof HTMLElement) {
|
|
184
|
+
const style = window.getComputedStyle(el);
|
|
185
|
+
if (style.display === "none" || style.visibility === "hidden")
|
|
186
|
+
return "";
|
|
187
|
+
}
|
|
188
|
+
const children = () => Array.from(el.childNodes).map(n => nodeToMd(n, depth)).join("");
|
|
189
|
+
if (tag === "h1")
|
|
190
|
+
return `\n\n# ${children().trim()}\n\n`;
|
|
191
|
+
if (tag === "h2")
|
|
192
|
+
return `\n\n## ${children().trim()}\n\n`;
|
|
193
|
+
if (tag === "h3")
|
|
194
|
+
return `\n\n### ${children().trim()}\n\n`;
|
|
195
|
+
if (tag === "h4")
|
|
196
|
+
return `\n\n#### ${children().trim()}\n\n`;
|
|
197
|
+
if (tag === "h5")
|
|
198
|
+
return `\n\n##### ${children().trim()}\n\n`;
|
|
199
|
+
if (tag === "h6")
|
|
200
|
+
return `\n\n###### ${children().trim()}\n\n`;
|
|
201
|
+
if (tag === "br")
|
|
202
|
+
return "\n";
|
|
203
|
+
if (tag === "hr")
|
|
204
|
+
return "\n\n---\n\n";
|
|
205
|
+
if (["p", "div", "section", "article"].includes(tag)) {
|
|
206
|
+
const inner = children().trim();
|
|
207
|
+
return inner ? `\n\n${inner}\n\n` : "";
|
|
208
|
+
}
|
|
209
|
+
if (tag === "a") {
|
|
210
|
+
const anchor = el;
|
|
211
|
+
const href = anchor.href;
|
|
212
|
+
const text = children().trim();
|
|
213
|
+
if (!text)
|
|
214
|
+
return "";
|
|
215
|
+
if (href.startsWith("#"))
|
|
216
|
+
return text;
|
|
217
|
+
if (href.startsWith("javascript:"))
|
|
218
|
+
return text;
|
|
219
|
+
if (href && href !== text && text.length > 0)
|
|
220
|
+
return `[${text}](${href})`;
|
|
221
|
+
return text;
|
|
222
|
+
}
|
|
223
|
+
if (tag === "img") {
|
|
224
|
+
const img = el;
|
|
225
|
+
const alt = img.alt?.trim() || "";
|
|
226
|
+
const src = img.src;
|
|
227
|
+
if (!src || src.startsWith("data:"))
|
|
228
|
+
return alt || "";
|
|
229
|
+
return alt ? `` : ``;
|
|
230
|
+
}
|
|
231
|
+
if (["strong", "b"].includes(tag)) {
|
|
232
|
+
const inner = children().trim();
|
|
233
|
+
return inner ? `**${inner}**` : "";
|
|
234
|
+
}
|
|
235
|
+
if (["em", "i"].includes(tag)) {
|
|
236
|
+
const inner = children().trim();
|
|
237
|
+
return inner ? `*${inner}*` : "";
|
|
238
|
+
}
|
|
239
|
+
if (tag === "code") {
|
|
240
|
+
const inner = children().trim();
|
|
241
|
+
return inner ? `\`${inner}\`` : "";
|
|
242
|
+
}
|
|
243
|
+
if (tag === "pre") {
|
|
244
|
+
const codeEl = el.querySelector("code");
|
|
245
|
+
const lang = codeEl?.className.match(/language-(\w+)/)?.[1] || "";
|
|
246
|
+
const text = (codeEl || el).textContent?.trim() || "";
|
|
247
|
+
return text ? `\n\n\`\`\`${lang}\n${text}\n\`\`\`\n\n` : "";
|
|
248
|
+
}
|
|
249
|
+
if (tag === "blockquote") {
|
|
250
|
+
const inner = children().trim();
|
|
251
|
+
if (!inner)
|
|
252
|
+
return "";
|
|
253
|
+
return "\n\n" + inner.split("\n").map(l => `> ${l}`).join("\n") + "\n\n";
|
|
254
|
+
}
|
|
255
|
+
if (tag === "ul") {
|
|
256
|
+
const items = Array.from(el.children)
|
|
257
|
+
.filter(c => c.tagName.toLowerCase() === "li")
|
|
258
|
+
.map(li => {
|
|
259
|
+
const text = nodeToMd(li, depth + 1).trim();
|
|
260
|
+
const indent = " ".repeat(depth);
|
|
261
|
+
return `${indent}- ${text}`;
|
|
262
|
+
});
|
|
263
|
+
return items.length ? `\n\n${items.join("\n")}\n\n` : "";
|
|
264
|
+
}
|
|
265
|
+
if (tag === "ol") {
|
|
266
|
+
const items = Array.from(el.children)
|
|
267
|
+
.filter(c => c.tagName.toLowerCase() === "li")
|
|
268
|
+
.map((li, i) => {
|
|
269
|
+
const text = nodeToMd(li, depth + 1).trim();
|
|
270
|
+
const indent = " ".repeat(depth);
|
|
271
|
+
return `${indent}${i + 1}. ${text}`;
|
|
272
|
+
});
|
|
273
|
+
return items.length ? `\n\n${items.join("\n")}\n\n` : "";
|
|
274
|
+
}
|
|
275
|
+
if (tag === "li")
|
|
276
|
+
return children();
|
|
277
|
+
if (tag === "table") {
|
|
278
|
+
const rows = Array.from(el.querySelectorAll("tr"));
|
|
279
|
+
if (rows.length === 0)
|
|
280
|
+
return "";
|
|
281
|
+
const toRow = (row) => Array.from(row.querySelectorAll("th,td"))
|
|
282
|
+
.map(cell => cell.textContent?.replace(/\s+/g, " ").trim() || "")
|
|
283
|
+
.join(" | ");
|
|
284
|
+
const firstRow = rows[0];
|
|
285
|
+
if (!firstRow)
|
|
286
|
+
return "";
|
|
287
|
+
const isHeaderRow = firstRow.querySelectorAll("th").length > 0;
|
|
288
|
+
const headerText = toRow(firstRow);
|
|
289
|
+
const cols = firstRow.querySelectorAll("th,td").length;
|
|
290
|
+
if (cols === 0)
|
|
291
|
+
return "";
|
|
292
|
+
const separator = Array(cols).fill("---").join(" | ");
|
|
293
|
+
const dataRows = isHeaderRow ? rows.slice(1) : rows;
|
|
294
|
+
const bodyLines = dataRows.map(r => `| ${toRow(r)} |`).join("\n");
|
|
295
|
+
return `\n\n| ${headerText} |\n| ${separator} |\n${bodyLines}\n\n`;
|
|
296
|
+
}
|
|
297
|
+
return children();
|
|
298
|
+
}
|
|
299
|
+
let md = nodeToMd(mainContent);
|
|
300
|
+
md = md.replace(/\n{3,}/g, "\n\n");
|
|
301
|
+
md = md.replace(/[ \t]+$/gm, "");
|
|
302
|
+
md = md.trim();
|
|
303
|
+
return md;
|
|
304
|
+
});
|
|
305
|
+
let output = `# Source: ${url}\n\n${extracted}`;
|
|
306
|
+
const words = output.split(/\s+/);
|
|
307
|
+
if (words.length > maxWords) {
|
|
308
|
+
return words.slice(0, maxWords).join(" ") +
|
|
309
|
+
`\n\n---\n*Truncated: ${words.length} words → ${maxWords} words*`;
|
|
310
|
+
}
|
|
311
|
+
if (!output) {
|
|
312
|
+
throw new Error(`Failed to fetch content from ${url} - received empty response`);
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
content: output,
|
|
316
|
+
size: output.length
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
return {
|
|
321
|
+
error: error instanceof Error ? error.message : String(error),
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
finally {
|
|
325
|
+
await browser?.close();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
export default ReadWebPageTool;
|
|
330
|
+
//# sourceMappingURL=read-web-page.js.map
|