decant-core 1.2.3 → 1.2.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/ai/google_search_ai.js +68 -3
- package/package.json +1 -1
package/ai/google_search_ai.js
CHANGED
|
@@ -1,6 +1,70 @@
|
|
|
1
1
|
import { ChatParser } from "./base.js";
|
|
2
2
|
import { convertToMarkdown } from "../utils/html-to-markdown.js";
|
|
3
3
|
|
|
4
|
+
export function sanitizeResponseContainer(container) {
|
|
5
|
+
if (!container) return container;
|
|
6
|
+
const clone =
|
|
7
|
+
typeof container.cloneNode === "function"
|
|
8
|
+
? container.cloneNode(true)
|
|
9
|
+
: container;
|
|
10
|
+
|
|
11
|
+
// 1. Remove script, style, and noscript elements to prevent inline script leakage
|
|
12
|
+
const unwanted = clone.querySelectorAll
|
|
13
|
+
? clone.querySelectorAll("script, style, noscript")
|
|
14
|
+
: [];
|
|
15
|
+
unwanted.forEach((el) => el.remove());
|
|
16
|
+
|
|
17
|
+
// 2. Remove base64 inline images to prevent megabyte-scale text walls in markdown exports
|
|
18
|
+
const images = clone.querySelectorAll ? clone.querySelectorAll("img") : [];
|
|
19
|
+
images.forEach((img) => {
|
|
20
|
+
const src = img.getAttribute("src") || "";
|
|
21
|
+
if (src.startsWith("data:image/")) {
|
|
22
|
+
img.remove();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// 3. Unwrap Google tracking redirects (/goto?url=..., /url?q=...) to direct URLs
|
|
27
|
+
const links = clone.querySelectorAll ? clone.querySelectorAll("a[href]") : [];
|
|
28
|
+
links.forEach((a) => {
|
|
29
|
+
const href = a.getAttribute("href") || "";
|
|
30
|
+
if (
|
|
31
|
+
href.startsWith("/goto?") ||
|
|
32
|
+
href.startsWith("/url?") ||
|
|
33
|
+
href.includes("google.com/url?") ||
|
|
34
|
+
href.includes("google.com/goto?")
|
|
35
|
+
) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = new URL(href, "https://www.google.com");
|
|
38
|
+
const target =
|
|
39
|
+
parsed.searchParams.get("url") || parsed.searchParams.get("q");
|
|
40
|
+
if (
|
|
41
|
+
target &&
|
|
42
|
+
(target.startsWith("http://") || target.startsWith("https://"))
|
|
43
|
+
) {
|
|
44
|
+
a.setAttribute("href", target);
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
// Keep original href if URL parsing fails
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 4. Remove empty link shells left behind by stripped images/tracking icons
|
|
52
|
+
if (!a.textContent.trim() && !a.querySelector("img, svg")) {
|
|
53
|
+
a.remove();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return clone;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function cleanMarkdownSpacing(markdown) {
|
|
61
|
+
if (!markdown) return "";
|
|
62
|
+
return markdown
|
|
63
|
+
.replace(/[ \t]+$/gm, "")
|
|
64
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
65
|
+
.trim();
|
|
66
|
+
}
|
|
67
|
+
|
|
4
68
|
export class GoogleSearchAIParser extends ChatParser {
|
|
5
69
|
name = "Google Search AI";
|
|
6
70
|
isAvailable(url) {
|
|
@@ -94,9 +158,10 @@ export class GoogleSearchAIParser extends ChatParser {
|
|
|
94
158
|
const minLength = Math.min(queries.length, responseContainers.length);
|
|
95
159
|
for (let i = 0; i < minLength; i++) {
|
|
96
160
|
messages.push({ role: "User", content: queries[i].trim() });
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
161
|
+
const cleanContainer = sanitizeResponseContainer(responseContainers[i]);
|
|
162
|
+
const text = cleanMarkdownSpacing(convertToMarkdown(cleanContainer));
|
|
163
|
+
if (text) {
|
|
164
|
+
messages.push({ role: "Model", content: text });
|
|
100
165
|
}
|
|
101
166
|
}
|
|
102
167
|
|