sentienceapi 0.92.2__py3-none-any.whl → 0.98.0__py3-none-any.whl
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.
Potentially problematic release.
This version of sentienceapi might be problematic. Click here for more details.
- sentience/__init__.py +107 -2
- sentience/_extension_loader.py +156 -1
- sentience/action_executor.py +2 -0
- sentience/actions.py +354 -9
- sentience/agent.py +4 -0
- sentience/agent_runtime.py +840 -0
- sentience/asserts/__init__.py +70 -0
- sentience/asserts/expect.py +621 -0
- sentience/asserts/query.py +383 -0
- sentience/async_api.py +8 -1
- sentience/backends/__init__.py +137 -0
- sentience/backends/actions.py +372 -0
- sentience/backends/browser_use_adapter.py +241 -0
- sentience/backends/cdp_backend.py +393 -0
- sentience/backends/exceptions.py +211 -0
- sentience/backends/playwright_backend.py +194 -0
- sentience/backends/protocol.py +216 -0
- sentience/backends/sentience_context.py +469 -0
- sentience/backends/snapshot.py +483 -0
- sentience/browser.py +230 -74
- sentience/canonicalization.py +207 -0
- sentience/cloud_tracing.py +65 -24
- sentience/constants.py +6 -0
- sentience/cursor_policy.py +142 -0
- sentience/extension/content.js +35 -0
- sentience/extension/injected_api.js +310 -15
- sentience/extension/manifest.json +1 -1
- sentience/extension/pkg/sentience_core.d.ts +22 -22
- sentience/extension/pkg/sentience_core.js +192 -144
- sentience/extension/pkg/sentience_core_bg.wasm +0 -0
- sentience/extension/release.json +29 -29
- sentience/failure_artifacts.py +241 -0
- sentience/integrations/__init__.py +6 -0
- sentience/integrations/langchain/__init__.py +12 -0
- sentience/integrations/langchain/context.py +18 -0
- sentience/integrations/langchain/core.py +326 -0
- sentience/integrations/langchain/tools.py +180 -0
- sentience/integrations/models.py +46 -0
- sentience/integrations/pydanticai/__init__.py +15 -0
- sentience/integrations/pydanticai/deps.py +20 -0
- sentience/integrations/pydanticai/toolset.py +468 -0
- sentience/llm_provider.py +695 -18
- sentience/models.py +536 -3
- sentience/ordinal.py +280 -0
- sentience/query.py +66 -4
- sentience/schemas/trace_v1.json +27 -1
- sentience/snapshot.py +384 -93
- sentience/snapshot_diff.py +39 -54
- sentience/text_search.py +1 -0
- sentience/trace_event_builder.py +20 -1
- sentience/trace_indexing/indexer.py +3 -49
- sentience/tracer_factory.py +1 -3
- sentience/verification.py +618 -0
- sentience/visual_agent.py +3 -1
- {sentienceapi-0.92.2.dist-info → sentienceapi-0.98.0.dist-info}/METADATA +198 -40
- sentienceapi-0.98.0.dist-info/RECORD +92 -0
- sentience/utils.py +0 -296
- sentienceapi-0.92.2.dist-info/RECORD +0 -65
- {sentienceapi-0.92.2.dist-info → sentienceapi-0.98.0.dist-info}/WHEEL +0 -0
- {sentienceapi-0.92.2.dist-info → sentienceapi-0.98.0.dist-info}/entry_points.txt +0 -0
- {sentienceapi-0.92.2.dist-info → sentienceapi-0.98.0.dist-info}/licenses/LICENSE +0 -0
- {sentienceapi-0.92.2.dist-info → sentienceapi-0.98.0.dist-info}/licenses/LICENSE-APACHE +0 -0
- {sentienceapi-0.92.2.dist-info → sentienceapi-0.98.0.dist-info}/licenses/LICENSE-MIT +0 -0
- {sentienceapi-0.92.2.dist-info → sentienceapi-0.98.0.dist-info}/top_level.txt +0 -0
|
@@ -10,6 +10,165 @@
|
|
|
10
10
|
}
|
|
11
11
|
return elements;
|
|
12
12
|
}
|
|
13
|
+
const CAPTCHA_TEXT_KEYWORDS = [ "verify you are human", "captcha", "human verification", "unusual traffic", "are you a robot", "security check", "prove you are human", "bot detection", "automated access" ], CAPTCHA_URL_HINTS = [ "captcha", "challenge", "verify" ], CAPTCHA_IFRAME_HINTS = {
|
|
14
|
+
recaptcha: [ "recaptcha", "google.com/recaptcha" ],
|
|
15
|
+
hcaptcha: [ "hcaptcha.com" ],
|
|
16
|
+
turnstile: [ "challenges.cloudflare.com", "turnstile" ],
|
|
17
|
+
arkose: [ "arkoselabs.com", "funcaptcha.com", "client-api.arkoselabs.com" ],
|
|
18
|
+
awswaf: [ "amazonaws.com/captcha", "awswaf.com" ]
|
|
19
|
+
}, CAPTCHA_SCRIPT_HINTS = {
|
|
20
|
+
recaptcha: [ "recaptcha" ],
|
|
21
|
+
hcaptcha: [ "hcaptcha" ],
|
|
22
|
+
turnstile: [ "turnstile", "challenges.cloudflare.com" ],
|
|
23
|
+
arkose: [ "arkoselabs", "funcaptcha" ],
|
|
24
|
+
awswaf: [ "captcha.awswaf", "awswaf-captcha" ]
|
|
25
|
+
}, CAPTCHA_CONTAINER_SELECTORS = [ {
|
|
26
|
+
selector: ".g-recaptcha",
|
|
27
|
+
provider: "recaptcha"
|
|
28
|
+
}, {
|
|
29
|
+
selector: "#g-recaptcha",
|
|
30
|
+
provider: "recaptcha"
|
|
31
|
+
}, {
|
|
32
|
+
selector: "[data-sitekey]",
|
|
33
|
+
provider: "unknown"
|
|
34
|
+
}, {
|
|
35
|
+
selector: 'iframe[title*="recaptcha" i]',
|
|
36
|
+
provider: "recaptcha"
|
|
37
|
+
}, {
|
|
38
|
+
selector: ".h-captcha",
|
|
39
|
+
provider: "hcaptcha"
|
|
40
|
+
}, {
|
|
41
|
+
selector: "#h-captcha",
|
|
42
|
+
provider: "hcaptcha"
|
|
43
|
+
}, {
|
|
44
|
+
selector: 'iframe[title*="hcaptcha" i]',
|
|
45
|
+
provider: "hcaptcha"
|
|
46
|
+
}, {
|
|
47
|
+
selector: ".cf-turnstile",
|
|
48
|
+
provider: "turnstile"
|
|
49
|
+
}, {
|
|
50
|
+
selector: "[data-cf-turnstile-sitekey]",
|
|
51
|
+
provider: "turnstile"
|
|
52
|
+
}, {
|
|
53
|
+
selector: 'iframe[src*="challenges.cloudflare.com"]',
|
|
54
|
+
provider: "turnstile"
|
|
55
|
+
}, {
|
|
56
|
+
selector: "#FunCaptcha",
|
|
57
|
+
provider: "arkose"
|
|
58
|
+
}, {
|
|
59
|
+
selector: ".funcaptcha",
|
|
60
|
+
provider: "arkose"
|
|
61
|
+
}, {
|
|
62
|
+
selector: "[data-arkose-public-key]",
|
|
63
|
+
provider: "arkose"
|
|
64
|
+
}, {
|
|
65
|
+
selector: 'iframe[src*="arkoselabs"]',
|
|
66
|
+
provider: "arkose"
|
|
67
|
+
}, {
|
|
68
|
+
selector: "#captcha-container",
|
|
69
|
+
provider: "awswaf"
|
|
70
|
+
}, {
|
|
71
|
+
selector: "[data-awswaf-captcha]",
|
|
72
|
+
provider: "awswaf"
|
|
73
|
+
}, {
|
|
74
|
+
selector: 'iframe[title*="captcha" i]',
|
|
75
|
+
provider: "unknown"
|
|
76
|
+
} ];
|
|
77
|
+
function addEvidence(list, value) {
|
|
78
|
+
value && (list.length >= 5 || list.push(value));
|
|
79
|
+
}
|
|
80
|
+
function truncateText(text, maxLen) {
|
|
81
|
+
return text ? text.length <= maxLen ? text : text.slice(0, maxLen) : "";
|
|
82
|
+
}
|
|
83
|
+
function matchHints(value, hints) {
|
|
84
|
+
const lower = String(value || "").toLowerCase();
|
|
85
|
+
return !!lower && hints.some(hint => lower.includes(hint));
|
|
86
|
+
}
|
|
87
|
+
function detectCaptcha() {
|
|
88
|
+
const evidence = {
|
|
89
|
+
text_hits: [],
|
|
90
|
+
selector_hits: [],
|
|
91
|
+
iframe_src_hits: [],
|
|
92
|
+
url_hits: []
|
|
93
|
+
};
|
|
94
|
+
let hasIframeHit = !1, hasContainerHit = !1, hasScriptHit = !1, hasKeywordHit = !1, hasUrlHit = !1;
|
|
95
|
+
const providerSignals = {
|
|
96
|
+
recaptcha: 0,
|
|
97
|
+
hcaptcha: 0,
|
|
98
|
+
turnstile: 0,
|
|
99
|
+
arkose: 0,
|
|
100
|
+
awswaf: 0
|
|
101
|
+
};
|
|
102
|
+
try {
|
|
103
|
+
const iframes = document.querySelectorAll("iframe");
|
|
104
|
+
for (const iframe of iframes) {
|
|
105
|
+
const src = iframe.getAttribute("src") || "", title = iframe.getAttribute("title") || "";
|
|
106
|
+
if (src) for (const [provider, hints] of Object.entries(CAPTCHA_IFRAME_HINTS)) matchHints(src, hints) && (hasIframeHit = !0,
|
|
107
|
+
providerSignals[provider] += 1, addEvidence(evidence.iframe_src_hits, truncateText(src, 120)));
|
|
108
|
+
if (title && matchHints(title, [ "captcha", "recaptcha" ]) && (hasContainerHit = !0,
|
|
109
|
+
addEvidence(evidence.selector_hits, 'iframe[title*="captcha"]')), evidence.iframe_src_hits.length >= 5) break;
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {}
|
|
112
|
+
try {
|
|
113
|
+
const scripts = document.querySelectorAll("script[src]");
|
|
114
|
+
for (const script of scripts) {
|
|
115
|
+
const src = script.getAttribute("src") || "";
|
|
116
|
+
if (src) {
|
|
117
|
+
for (const [provider, hints] of Object.entries(CAPTCHA_SCRIPT_HINTS)) matchHints(src, hints) && (hasScriptHit = !0,
|
|
118
|
+
providerSignals[provider] += 1, addEvidence(evidence.selector_hits, `script[src*="${hints[0]}"]`));
|
|
119
|
+
if (evidence.selector_hits.length >= 5) break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} catch (e) {}
|
|
123
|
+
for (const {selector: selector, provider: provider} of CAPTCHA_CONTAINER_SELECTORS) try {
|
|
124
|
+
document.querySelector(selector) && (hasContainerHit = !0, addEvidence(evidence.selector_hits, selector),
|
|
125
|
+
"unknown" !== provider && (providerSignals[provider] += 1));
|
|
126
|
+
} catch (e) {}
|
|
127
|
+
const textSnippet = function() {
|
|
128
|
+
try {
|
|
129
|
+
const candidates = document.querySelectorAll("h1, h2, h3, h4, p, label, button, form, div, span");
|
|
130
|
+
let combined = "", count = 0;
|
|
131
|
+
for (const node of candidates) {
|
|
132
|
+
if (count >= 30 || combined.length >= 2e3) break;
|
|
133
|
+
if (!node || "string" != typeof node.innerText) continue;
|
|
134
|
+
if (!node.offsetWidth && !node.offsetHeight && !node.getClientRects().length) continue;
|
|
135
|
+
const text = node.innerText.replace(/\s+/g, " ").trim();
|
|
136
|
+
text && (combined += `${text} `, count += 1);
|
|
137
|
+
}
|
|
138
|
+
if (combined = combined.trim(), combined) return truncateText(combined, 2e3);
|
|
139
|
+
} catch (e) {}
|
|
140
|
+
try {
|
|
141
|
+
let bodyText = document.body?.innerText || "";
|
|
142
|
+
return !bodyText && document.body?.textContent && (bodyText = document.body.textContent),
|
|
143
|
+
truncateText(bodyText.replace(/\s+/g, " ").trim(), 2e3);
|
|
144
|
+
} catch (e) {
|
|
145
|
+
return "";
|
|
146
|
+
}
|
|
147
|
+
}();
|
|
148
|
+
if (textSnippet) {
|
|
149
|
+
const lowerText = textSnippet.toLowerCase();
|
|
150
|
+
for (const keyword of CAPTCHA_TEXT_KEYWORDS) lowerText.includes(keyword) && (hasKeywordHit = !0,
|
|
151
|
+
addEvidence(evidence.text_hits, keyword));
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const lowerUrl = (window.location?.href || "").toLowerCase();
|
|
155
|
+
for (const hint of CAPTCHA_URL_HINTS) lowerUrl.includes(hint) && (hasUrlHit = !0,
|
|
156
|
+
addEvidence(evidence.url_hits, hint));
|
|
157
|
+
} catch (e) {}
|
|
158
|
+
let confidence = 0;
|
|
159
|
+
hasIframeHit && (confidence += .7), hasContainerHit && (confidence += .5), hasScriptHit && (confidence += .5),
|
|
160
|
+
hasKeywordHit && (confidence += .3), hasUrlHit && (confidence += .2), confidence = Math.min(1, confidence),
|
|
161
|
+
hasIframeHit && (confidence = Math.max(confidence, .8)), !hasKeywordHit || hasIframeHit || hasContainerHit || hasScriptHit || hasUrlHit || (confidence = Math.min(confidence, .4));
|
|
162
|
+
const detected = confidence >= .7;
|
|
163
|
+
let providerHint = null;
|
|
164
|
+
return providerSignals.recaptcha > 0 ? providerHint = "recaptcha" : providerSignals.hcaptcha > 0 ? providerHint = "hcaptcha" : providerSignals.turnstile > 0 ? providerHint = "turnstile" : providerSignals.arkose > 0 ? providerHint = "arkose" : providerSignals.awswaf > 0 ? providerHint = "awswaf" : detected && (providerHint = "unknown"),
|
|
165
|
+
{
|
|
166
|
+
detected: detected,
|
|
167
|
+
provider_hint: providerHint,
|
|
168
|
+
confidence: confidence,
|
|
169
|
+
evidence: evidence
|
|
170
|
+
};
|
|
171
|
+
}
|
|
13
172
|
const DEFAULT_INFERENCE_CONFIG = {
|
|
14
173
|
allowedTags: [ "label", "span", "div" ],
|
|
15
174
|
allowedRoles: [],
|
|
@@ -157,8 +316,28 @@
|
|
|
157
316
|
}
|
|
158
317
|
return null;
|
|
159
318
|
}
|
|
319
|
+
function normalizeNearbyText(text) {
|
|
320
|
+
return text ? text.replace(/\s+/g, " ").trim() : "";
|
|
321
|
+
}
|
|
322
|
+
function isInteractableElement(el) {
|
|
323
|
+
if (!el || !el.tagName) return !1;
|
|
324
|
+
const tag = el.tagName.toLowerCase(), role = el.getAttribute ? el.getAttribute("role") : null, hasTabIndex = !!el.hasAttribute && el.hasAttribute("tabindex"), hasHref = "A" === el.tagName && !!el.hasAttribute && el.hasAttribute("href");
|
|
325
|
+
if ([ "button", "input", "textarea", "select", "option", "details", "summary", "a" ].includes(tag)) return !("a" === tag && !hasHref);
|
|
326
|
+
if (role && [ "button", "link", "tab", "menuitem", "checkbox", "radio", "switch", "slider", "combobox", "textbox", "searchbox", "spinbutton" ].includes(role.toLowerCase())) return !0;
|
|
327
|
+
if (hasTabIndex) return !0;
|
|
328
|
+
if (el.onclick || el.onkeydown || el.onkeypress || el.onkeyup) return !0;
|
|
329
|
+
if (el.getAttribute) {
|
|
330
|
+
if (el.getAttribute("onclick") || el.getAttribute("onkeydown") || el.getAttribute("onkeypress") || el.getAttribute("onkeyup")) return !0;
|
|
331
|
+
}
|
|
332
|
+
return !1;
|
|
333
|
+
}
|
|
160
334
|
function getText(el) {
|
|
161
|
-
|
|
335
|
+
if (el.getAttribute("aria-label")) return el.getAttribute("aria-label");
|
|
336
|
+
if ("INPUT" === el.tagName) {
|
|
337
|
+
const t = el.getAttribute && el.getAttribute("type") || el.type || "";
|
|
338
|
+
return "password" === String(t).toLowerCase() ? el.placeholder || "" : el.value || el.placeholder || "";
|
|
339
|
+
}
|
|
340
|
+
return "IMG" === el.tagName ? el.alt || "" : (el.innerText || "").replace(/\s+/g, " ").trim().substring(0, 100);
|
|
162
341
|
}
|
|
163
342
|
function getClassName(el) {
|
|
164
343
|
if (!el || !el.className) return "";
|
|
@@ -268,11 +447,17 @@
|
|
|
268
447
|
try {
|
|
269
448
|
!1 !== options.waitForStability && await async function(options = {}) {
|
|
270
449
|
const {minNodeCount: minNodeCount = 500, quietPeriod: quietPeriod = 200, maxWait: maxWait = 5e3} = options, startTime = Date.now();
|
|
450
|
+
try {
|
|
451
|
+
window.__sentience_lastMutationTs = performance.now();
|
|
452
|
+
} catch (e) {}
|
|
271
453
|
return new Promise(resolve => {
|
|
272
454
|
if (document.querySelectorAll("*").length >= minNodeCount) {
|
|
273
455
|
let lastChange = Date.now();
|
|
274
456
|
const observer = new MutationObserver(() => {
|
|
275
457
|
lastChange = Date.now();
|
|
458
|
+
try {
|
|
459
|
+
window.__sentience_lastMutationTs = performance.now();
|
|
460
|
+
} catch (e) {}
|
|
276
461
|
});
|
|
277
462
|
observer.observe(document.body, {
|
|
278
463
|
childList: !0,
|
|
@@ -288,11 +473,17 @@
|
|
|
288
473
|
} else {
|
|
289
474
|
const observer = new MutationObserver(() => {
|
|
290
475
|
const currentCount = document.querySelectorAll("*").length, totalWait = Date.now() - startTime;
|
|
476
|
+
try {
|
|
477
|
+
window.__sentience_lastMutationTs = performance.now();
|
|
478
|
+
} catch (e) {}
|
|
291
479
|
if (currentCount >= minNodeCount) {
|
|
292
480
|
observer.disconnect();
|
|
293
481
|
let lastChange = Date.now();
|
|
294
482
|
const quietObserver = new MutationObserver(() => {
|
|
295
483
|
lastChange = Date.now();
|
|
484
|
+
try {
|
|
485
|
+
window.__sentience_lastMutationTs = performance.now();
|
|
486
|
+
} catch (e) {}
|
|
296
487
|
});
|
|
297
488
|
quietObserver.observe(document.body, {
|
|
298
489
|
childList: !0,
|
|
@@ -323,8 +514,15 @@
|
|
|
323
514
|
if (!el.getBoundingClientRect) return;
|
|
324
515
|
const rect = el.getBoundingClientRect();
|
|
325
516
|
if (rect.width < 5 || rect.height < 5) return;
|
|
517
|
+
const tagName = el.tagName.toLowerCase();
|
|
518
|
+
if ("span" === tagName) {
|
|
519
|
+
if (el.closest("a")) return;
|
|
520
|
+
const childLink = el.querySelector("a[href]");
|
|
521
|
+
if (childLink && childLink.href) return;
|
|
522
|
+
options.debug && el.className && el.className.includes("titleline");
|
|
523
|
+
}
|
|
326
524
|
window.sentience_registry[idx] = el;
|
|
327
|
-
const semanticText = function(el, options = {}) {
|
|
525
|
+
const inputType = "input" === tagName ? toSafeString(el.getAttribute && el.getAttribute("type") || el.type || null) : null, isPasswordInput = inputType && "password" === inputType.toLowerCase(), semanticText = function(el, options = {}) {
|
|
328
526
|
if (!el) return {
|
|
329
527
|
text: "",
|
|
330
528
|
source: null
|
|
@@ -335,10 +533,10 @@
|
|
|
335
533
|
source: "explicit_aria_label"
|
|
336
534
|
};
|
|
337
535
|
if ("INPUT" === el.tagName) {
|
|
338
|
-
const value = (el.value || el.placeholder || "").trim();
|
|
536
|
+
const t = el.getAttribute && el.getAttribute("type") || el.type || "", isPassword = "password" === String(t).toLowerCase(), value = (isPassword ? el.placeholder || "" : el.value || el.placeholder || "").trim();
|
|
339
537
|
if (value) return {
|
|
340
538
|
text: value,
|
|
341
|
-
source: "input_value"
|
|
539
|
+
source: isPassword ? "input_placeholder" : "input_value"
|
|
342
540
|
};
|
|
343
541
|
}
|
|
344
542
|
if ("IMG" === el.tagName) {
|
|
@@ -367,11 +565,7 @@
|
|
|
367
565
|
}), textVal = semanticText.text || getText(el), inferredRole = function(el, options = {}) {
|
|
368
566
|
const {enableInference: enableInference = !0} = options;
|
|
369
567
|
if (!enableInference) return null;
|
|
370
|
-
if (!
|
|
371
|
-
if (!el || !el.tagName) return !1;
|
|
372
|
-
const tag = el.tagName.toLowerCase(), role = el.getAttribute ? el.getAttribute("role") : null, hasTabIndex = !!el.hasAttribute && el.hasAttribute("tabindex"), hasHref = "A" === el.tagName && !!el.hasAttribute && el.hasAttribute("href");
|
|
373
|
-
return [ "button", "input", "textarea", "select", "option", "details", "summary", "a" ].includes(tag) ? !("a" === tag && !hasHref) : !(!role || ![ "button", "link", "tab", "menuitem", "checkbox", "radio", "switch", "slider", "combobox", "textbox", "searchbox", "spinbutton" ].includes(role.toLowerCase())) || (!!hasTabIndex || (!!(el.onclick || el.onkeydown || el.onkeypress || el.onkeyup) || !(!el.getAttribute || !(el.getAttribute("onclick") || el.getAttribute("onkeydown") || el.getAttribute("onkeypress") || el.getAttribute("onkeyup")))));
|
|
374
|
-
}(el)) return null;
|
|
568
|
+
if (!isInteractableElement(el)) return null;
|
|
375
569
|
const hasAriaLabel = el.getAttribute ? el.getAttribute("aria-label") : null, hasExplicitRole = el.getAttribute ? el.getAttribute("role") : null;
|
|
376
570
|
if (hasAriaLabel || hasExplicitRole) return null;
|
|
377
571
|
const tag = el.tagName.toLowerCase();
|
|
@@ -411,9 +605,79 @@
|
|
|
411
605
|
}
|
|
412
606
|
return null;
|
|
413
607
|
}(el);
|
|
608
|
+
let safeValue = null, valueRedacted = null;
|
|
609
|
+
try {
|
|
610
|
+
if (void 0 !== el.value || el.getAttribute && null !== el.getAttribute("value")) if (isPasswordInput) safeValue = null,
|
|
611
|
+
valueRedacted = "true"; else {
|
|
612
|
+
const rawValue = void 0 !== el.value ? String(el.value) : String(el.getAttribute("value"));
|
|
613
|
+
safeValue = rawValue.length > 200 ? rawValue.substring(0, 200) : rawValue, valueRedacted = "false";
|
|
614
|
+
}
|
|
615
|
+
} catch (e) {}
|
|
616
|
+
const accessibleName = toSafeString(function(el) {
|
|
617
|
+
if (!el || !el.getAttribute) return "";
|
|
618
|
+
const ariaLabel = el.getAttribute("aria-label");
|
|
619
|
+
if (ariaLabel && ariaLabel.trim()) return ariaLabel.trim().substring(0, 200);
|
|
620
|
+
const labelledBy = el.getAttribute("aria-labelledby");
|
|
621
|
+
if (labelledBy && labelledBy.trim()) {
|
|
622
|
+
const ids = labelledBy.split(/\s+/).filter(id => id.trim()), texts = [];
|
|
623
|
+
for (const id of ids) try {
|
|
624
|
+
const ref = document.getElementById(id);
|
|
625
|
+
if (!ref) continue;
|
|
626
|
+
const txt = (ref.innerText || ref.textContent || ref.getAttribute?.("aria-label") || "").toString().trim();
|
|
627
|
+
txt && texts.push(txt);
|
|
628
|
+
} catch (e) {}
|
|
629
|
+
if (texts.length > 0) return texts.join(" ").substring(0, 200);
|
|
630
|
+
}
|
|
631
|
+
try {
|
|
632
|
+
if (el.labels && el.labels.length > 0) {
|
|
633
|
+
const t = (el.labels[0].innerText || el.labels[0].textContent || "").toString().trim();
|
|
634
|
+
if (t) return t.substring(0, 200);
|
|
635
|
+
}
|
|
636
|
+
} catch (e) {}
|
|
637
|
+
try {
|
|
638
|
+
const parentLabel = el.closest && el.closest("label");
|
|
639
|
+
if (parentLabel) {
|
|
640
|
+
const t = (parentLabel.innerText || parentLabel.textContent || "").toString().trim();
|
|
641
|
+
if (t) return t.substring(0, 200);
|
|
642
|
+
}
|
|
643
|
+
} catch (e) {}
|
|
644
|
+
const tag = (el.tagName || "").toUpperCase();
|
|
645
|
+
if ("INPUT" === tag || "TEXTAREA" === tag) {
|
|
646
|
+
const ph = (el.getAttribute("placeholder") || "").toString().trim();
|
|
647
|
+
if (ph) return ph.substring(0, 200);
|
|
648
|
+
}
|
|
649
|
+
const title = el.getAttribute("title");
|
|
650
|
+
return title && title.trim() ? title.trim().substring(0, 200) : "";
|
|
651
|
+
}(el) || null), nearbyText = isInteractableElement(el) ? function(el, options = {}) {
|
|
652
|
+
if (!el) return null;
|
|
653
|
+
const maxLen = "number" == typeof options.maxLen ? options.maxLen : 80, ownText = normalizeNearbyText(el.innerText || ""), candidates = [], collect = node => {
|
|
654
|
+
if (!node) return;
|
|
655
|
+
let text = "";
|
|
656
|
+
try {
|
|
657
|
+
text = normalizeNearbyText(node.innerText || node.textContent || "");
|
|
658
|
+
} catch (e) {
|
|
659
|
+
text = "";
|
|
660
|
+
}
|
|
661
|
+
text && text !== ownText && candidates.push(text);
|
|
662
|
+
};
|
|
663
|
+
if (collect(el.previousElementSibling), collect(el.nextElementSibling), 0 === candidates.length && el.parentElement) {
|
|
664
|
+
let parentText = "";
|
|
665
|
+
try {
|
|
666
|
+
parentText = normalizeNearbyText(el.parentElement.innerText || "");
|
|
667
|
+
} catch (e) {
|
|
668
|
+
parentText = "";
|
|
669
|
+
}
|
|
670
|
+
parentText && parentText !== ownText && parentText.length <= 120 && candidates.push(parentText);
|
|
671
|
+
}
|
|
672
|
+
if (0 === candidates.length) return null;
|
|
673
|
+
let text = candidates[0];
|
|
674
|
+
return text.length > maxLen && (text = text.slice(0, maxLen).trim()), text || null;
|
|
675
|
+
}(el, {
|
|
676
|
+
maxLen: 80
|
|
677
|
+
}) : null;
|
|
414
678
|
rawData.push({
|
|
415
679
|
id: idx,
|
|
416
|
-
tag:
|
|
680
|
+
tag: tagName,
|
|
417
681
|
rect: {
|
|
418
682
|
x: rect.x,
|
|
419
683
|
y: rect.y,
|
|
@@ -435,18 +699,27 @@
|
|
|
435
699
|
attributes: {
|
|
436
700
|
role: toSafeString(el.getAttribute("role")),
|
|
437
701
|
type_: toSafeString(el.getAttribute("type")),
|
|
702
|
+
input_type: inputType,
|
|
438
703
|
aria_label: "explicit_aria_label" === semanticText?.source ? semanticText.text : toSafeString(el.getAttribute("aria-label")),
|
|
704
|
+
name: accessibleName,
|
|
439
705
|
inferred_label: semanticText?.source && ![ "explicit_aria_label", "input_value", "img_alt", "inner_text" ].includes(semanticText.source) ? toSafeString(semanticText.text) : null,
|
|
440
706
|
label_source: semanticText?.source || null,
|
|
441
707
|
inferred_role: inferredRole ? toSafeString(inferredRole) : null,
|
|
442
|
-
|
|
708
|
+
nearby_text: toSafeString(nearbyText),
|
|
709
|
+
href: toSafeString(el.href || el.getAttribute("href") || el.closest && el.closest("a")?.href || null),
|
|
443
710
|
class: toSafeString(getClassName(el)),
|
|
444
|
-
value:
|
|
445
|
-
|
|
711
|
+
value: null !== safeValue ? toSafeString(safeValue) : null,
|
|
712
|
+
value_redacted: valueRedacted,
|
|
713
|
+
checked: void 0 !== el.checked ? String(el.checked) : null,
|
|
714
|
+
disabled: void 0 !== el.disabled ? String(el.disabled) : null,
|
|
715
|
+
aria_checked: toSafeString(el.getAttribute("aria-checked")),
|
|
716
|
+
aria_disabled: toSafeString(el.getAttribute("aria-disabled")),
|
|
717
|
+
aria_expanded: toSafeString(el.getAttribute("aria-expanded"))
|
|
446
718
|
},
|
|
447
719
|
text: toSafeString(textVal),
|
|
448
720
|
in_viewport: inView,
|
|
449
|
-
is_occluded: occluded
|
|
721
|
+
is_occluded: occluded,
|
|
722
|
+
scroll_y: window.scrollY
|
|
450
723
|
});
|
|
451
724
|
});
|
|
452
725
|
const allRawElements = [ ...rawData ];
|
|
@@ -569,6 +842,18 @@
|
|
|
569
842
|
}(options.screenshot));
|
|
570
843
|
const cleanedElements = cleanElement(processed.elements), cleanedRawElements = cleanElement(processed.raw_elements);
|
|
571
844
|
cleanedElements.length, cleanedRawElements.length;
|
|
845
|
+
let diagnostics;
|
|
846
|
+
try {
|
|
847
|
+
const lastMutationTs = window.__sentience_lastMutationTs, now = performance.now(), quietMs = "number" == typeof lastMutationTs && Number.isFinite(lastMutationTs) ? Math.max(0, now - lastMutationTs) : null, nodeCount = document.querySelectorAll("*").length;
|
|
848
|
+
diagnostics = {
|
|
849
|
+
metrics: {
|
|
850
|
+
ready_state: document.readyState || null,
|
|
851
|
+
quiet_ms: quietMs,
|
|
852
|
+
node_count: nodeCount
|
|
853
|
+
},
|
|
854
|
+
captcha: detectCaptcha()
|
|
855
|
+
};
|
|
856
|
+
} catch (e) {}
|
|
572
857
|
return {
|
|
573
858
|
status: "success",
|
|
574
859
|
url: window.location.href,
|
|
@@ -578,7 +863,8 @@
|
|
|
578
863
|
},
|
|
579
864
|
elements: cleanedElements,
|
|
580
865
|
raw_elements: cleanedRawElements,
|
|
581
|
-
screenshot: screenshot
|
|
866
|
+
screenshot: screenshot,
|
|
867
|
+
diagnostics: diagnostics
|
|
582
868
|
};
|
|
583
869
|
} catch (error) {
|
|
584
870
|
return {
|
|
@@ -848,6 +1134,14 @@
|
|
|
848
1134
|
timestamp: Date.now()
|
|
849
1135
|
}, "*");
|
|
850
1136
|
}
|
|
1137
|
+
function showGrid(grids, targetGridId = null) {
|
|
1138
|
+
grids && Array.isArray(grids) && window.postMessage({
|
|
1139
|
+
type: "SENTIENCE_SHOW_GRID_OVERLAY",
|
|
1140
|
+
grids: grids,
|
|
1141
|
+
targetGridId: targetGridId,
|
|
1142
|
+
timestamp: Date.now()
|
|
1143
|
+
}, "*");
|
|
1144
|
+
}
|
|
851
1145
|
function clearOverlay() {
|
|
852
1146
|
window.postMessage({
|
|
853
1147
|
type: "SENTIENCE_CLEAR_OVERLAY"
|
|
@@ -868,6 +1162,7 @@
|
|
|
868
1162
|
click: click,
|
|
869
1163
|
startRecording: startRecording,
|
|
870
1164
|
showOverlay: showOverlay,
|
|
1165
|
+
showGrid: showGrid,
|
|
871
1166
|
clearOverlay: clearOverlay
|
|
872
1167
|
}, window.sentience_iframe_handler_setup || (window.addEventListener("message", async event => {
|
|
873
1168
|
if ("SENTIENCE_IFRAME_SNAPSHOT_REQUEST" === event.data?.type) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "Sentience Semantic Visual Grounding Extractor",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.7.0",
|
|
5
5
|
"description": "Extract semantic visual grounding data from web pages",
|
|
6
6
|
"permissions": ["activeTab", "scripting"],
|
|
7
7
|
"host_permissions": ["<all_urls>"],
|
|
@@ -18,34 +18,34 @@ export function prune_for_api(val: any): any;
|
|
|
18
18
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
19
19
|
|
|
20
20
|
export interface InitOutput {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
readonly memory: WebAssembly.Memory;
|
|
22
|
+
readonly analyze_page: (a: number) => number;
|
|
23
|
+
readonly analyze_page_with_options: (a: number, b: number) => number;
|
|
24
|
+
readonly decide_and_act: (a: number) => void;
|
|
25
|
+
readonly prune_for_api: (a: number) => number;
|
|
26
|
+
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
27
|
+
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
|
28
|
+
readonly __wbindgen_export3: (a: number) => void;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Instantiates the given `module`, which can either be bytes or
|
|
35
|
-
* a precompiled `WebAssembly.Module`.
|
|
36
|
-
*
|
|
37
|
-
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
38
|
-
*
|
|
39
|
-
* @returns {InitOutput}
|
|
40
|
-
*/
|
|
34
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
35
|
+
* a precompiled `WebAssembly.Module`.
|
|
36
|
+
*
|
|
37
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
38
|
+
*
|
|
39
|
+
* @returns {InitOutput}
|
|
40
|
+
*/
|
|
41
41
|
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
45
|
-
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
46
|
-
*
|
|
47
|
-
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
48
|
-
*
|
|
49
|
-
* @returns {Promise<InitOutput>}
|
|
50
|
-
*/
|
|
44
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
45
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
46
|
+
*
|
|
47
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
48
|
+
*
|
|
49
|
+
* @returns {Promise<InitOutput>}
|
|
50
|
+
*/
|
|
51
51
|
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|