@nuanu-ai/agentbrowse 0.2.35 → 0.2.37
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/dist/agentpay-gateway.d.ts.map +1 -1
- package/dist/agentpay-gateway.js +1 -22
- package/dist/commands/observe-accessibility.d.ts.map +1 -1
- package/dist/commands/observe-accessibility.js +35 -1
- package/dist/commands/observe-inventory.d.ts.map +1 -1
- package/dist/commands/observe-inventory.js +17 -4
- package/dist/commands/semantic-observe-lexical.d.ts +31 -0
- package/dist/commands/semantic-observe-lexical.d.ts.map +1 -0
- package/dist/commands/semantic-observe-lexical.js +188 -0
- package/dist/commands/semantic-observe.d.ts +1 -0
- package/dist/commands/semantic-observe.d.ts.map +1 -1
- package/dist/commands/semantic-observe.js +183 -97
- package/dist/control-semantics.d.ts.map +1 -1
- package/dist/control-semantics.js +84 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/solver/config.js +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentpay-gateway.d.ts","sourceRoot":"","sources":["../src/agentpay-gateway.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agentpay-gateway.d.ts","sourceRoot":"","sources":["../src/agentpay-gateway.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAYD,wBAAgB,+BAA+B,IAAI,qBAAqB,GAAG,IAAI,CAiB9E;AAED,wBAAgB,4BAA4B,IAAI,qBAAqB,CAMpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAG5E;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAI/E"}
|
package/dist/agentpay-gateway.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { readConfig } from './solver/config.js';
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
2
|
const DEFAULT_AGENTPAY_API_URL = 'https://durcottggsiesxxqzvbb.supabase.co/functions/v1/api';
|
|
6
3
|
function trimOrUndefined(value) {
|
|
7
4
|
if (!value)
|
|
@@ -12,30 +9,12 @@ function trimOrUndefined(value) {
|
|
|
12
9
|
function normalizeApiUrl(value) {
|
|
13
10
|
return value.replace(/\/$/, '');
|
|
14
11
|
}
|
|
15
|
-
function readAgentpayCliConfig() {
|
|
16
|
-
const primaryPath = join(homedir(), '.agentpay', 'config.json');
|
|
17
|
-
const legacyPath = join(homedir(), '.agentpay', 'agentpay-cli', 'config.json');
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(readFileSync(primaryPath, 'utf-8'));
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
try {
|
|
23
|
-
return JSON.parse(readFileSync(legacyPath, 'utf-8'));
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return {};
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
12
|
export function tryResolveAgentpayGatewayConfig() {
|
|
31
13
|
const solverConfig = readConfig();
|
|
32
|
-
const cliConfig = readAgentpayCliConfig();
|
|
33
14
|
const apiKey = trimOrUndefined(process.env.AGENTPAY_API_KEY) ||
|
|
34
|
-
trimOrUndefined(solverConfig.agentpay?.apiKey)
|
|
35
|
-
trimOrUndefined(cliConfig.agentpay?.apiKey);
|
|
15
|
+
trimOrUndefined(solverConfig.agentpay?.apiKey);
|
|
36
16
|
const apiUrl = trimOrUndefined(process.env.AGENTPAY_API_URL) ||
|
|
37
17
|
trimOrUndefined(solverConfig.agentpay?.apiUrl) ||
|
|
38
|
-
trimOrUndefined(cliConfig.agentpay?.apiUrl) ||
|
|
39
18
|
DEFAULT_AGENTPAY_API_URL;
|
|
40
19
|
if (!apiKey) {
|
|
41
20
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe-accessibility.d.ts","sourceRoot":"","sources":["../../src/commands/observe-accessibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"observe-accessibility.d.ts","sourceRoot":"","sources":["../../src/commands/observe-accessibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAa5C,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC,KAAK,6BAA6B,GAAG;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;CACpD,CAAC;AAOF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,CAAC;CACtD,CAAC;AAyDF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAClC,6BAA6B,GAAG,IAAI,CAoDtC;AAiqBD,wBAAsB,iCAAiC,CACrD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAY9B;AAED,eAAO,MAAM,0BAA0B;;CAEtC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveLocatorRoot } from './action-fallbacks.js';
|
|
2
2
|
import { buildObserveDisplayLabel } from './observe-display-label.js';
|
|
3
|
+
import { isButtonLikeObservedInput, shouldAllowLooseFieldLabelFallbackForObservedControl, } from './observe-label-policy.js';
|
|
3
4
|
import { fallbackContextNodeLabelOf, fallbackHintTextOf, fallbackSurfaceLabelOf, fallbackTargetLabelOf, } from './observe-fallback-semantics.js';
|
|
4
5
|
const AX_ENRICHMENT_CONCURRENCY = 12;
|
|
5
6
|
const AX_SNAPSHOT_TIMEOUT_MS = 250;
|
|
@@ -105,12 +106,39 @@ function shouldPreferAccessibilityName(target, accessibilityName) {
|
|
|
105
106
|
const currentKey = normalizeLabelKey(currentLabel);
|
|
106
107
|
const nextLabel = normalizeText(accessibilityName);
|
|
107
108
|
const visibleText = normalizeText(target.text);
|
|
109
|
+
const kind = normalizeText(target.kind)?.toLowerCase();
|
|
110
|
+
const role = normalizeText(target.role)?.toLowerCase();
|
|
111
|
+
const looseFieldFallbackAllowed = shouldAllowLooseFieldLabelFallbackForObservedControl({
|
|
112
|
+
tag: kind,
|
|
113
|
+
role,
|
|
114
|
+
inputType: target.inputType,
|
|
115
|
+
});
|
|
116
|
+
const primaryAxControl = !looseFieldFallbackAllowed &&
|
|
117
|
+
(kind === 'button' ||
|
|
118
|
+
kind === 'link' ||
|
|
119
|
+
kind === 'checkbox' ||
|
|
120
|
+
kind === 'radio' ||
|
|
121
|
+
role === 'button' ||
|
|
122
|
+
role === 'link' ||
|
|
123
|
+
role === 'checkbox' ||
|
|
124
|
+
role === 'radio' ||
|
|
125
|
+
role === 'menuitem' ||
|
|
126
|
+
role === 'option' ||
|
|
127
|
+
role === 'switch' ||
|
|
128
|
+
role === 'tab' ||
|
|
129
|
+
isButtonLikeObservedInput({
|
|
130
|
+
tag: kind,
|
|
131
|
+
inputType: target.inputType,
|
|
132
|
+
}));
|
|
108
133
|
if (!isMeaningfulName(nextLabel)) {
|
|
109
134
|
return false;
|
|
110
135
|
}
|
|
111
136
|
if (!isMeaningfulName(currentLabel)) {
|
|
112
137
|
return true;
|
|
113
138
|
}
|
|
139
|
+
if (primaryAxControl && currentLabel !== nextLabel) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
114
142
|
if (GENERIC_FALLBACK_LABELS.has(currentKey)) {
|
|
115
143
|
return true;
|
|
116
144
|
}
|
|
@@ -426,7 +454,13 @@ async function enrichTargetWithAccessibility(page, target, rootCache, snapshotCa
|
|
|
426
454
|
const landmarkDomFallback = await readDomFallbackSemantics(page, { selector: target.context?.landmark?.selector, framePath: target.framePath }, rootCache, fallbackCache);
|
|
427
455
|
const targetDomFallback = await readDomFallbackSemantics(page, target, rootCache, fallbackCache);
|
|
428
456
|
const nextLabel = isMeaningfulName(semantics?.name) &&
|
|
429
|
-
shouldPreferAccessibilityName({
|
|
457
|
+
shouldPreferAccessibilityName({
|
|
458
|
+
kind: target.kind,
|
|
459
|
+
role: target.role,
|
|
460
|
+
inputType: target.inputType,
|
|
461
|
+
label: fallbackTargetLabelOf(target),
|
|
462
|
+
text: target.text,
|
|
463
|
+
}, semantics.name)
|
|
430
464
|
? semantics.name
|
|
431
465
|
: chooseSemanticName(fallbackTargetLabelOf(target), semantics, stats);
|
|
432
466
|
const nextContext = target.context
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe-inventory.d.ts","sourceRoot":"","sources":["../../src/commands/observe-inventory.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"observe-inventory.d.ts","sourceRoot":"","sources":["../../src/commands/observe-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAe7B,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,GAAG;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,aAAa,EACb,MAAM,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,CAC5C,GAAG;IACF,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,aAAa,GAAG,cAAc,CAAC;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACvC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;CACpD,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,QAAQ,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,KAAK,6BAA6B,GAAG;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5F,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,kCAAkC,CAAC;CAC/C,CAAC;AAIF,wBAAgB,sCAAsC,CACpD,QAAQ,EAAE,6BAA6B,GACtC,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAwCrD;AAED,wBAAgB,2CAA2C,CACzD,QAAQ,EAAE,kCAAkC,GAC3C,MAAM,GAAG,SAAS,CAuCpB;AA2KD,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,wBAAwB,CAAC,CAuBnC;AAiED,iBAAS,8BAA8B,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAElF;AAED,iBAAe,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAOxF;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAyBA;AAED,iBAAe,6BAA6B,CAC1C,OAAO,EAAE,0BAA0B,EACnC,OAAO,CAAC,EAAE,0BAA0B,GAAG;IACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAk8E9B;AA6MD,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA0B/F;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE;IACJ,QAAQ,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,KAAK,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,EACD,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAqD9B;AAED,eAAO,MAAM,yBAAyB;;;;;CAKrC,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;CAKrC,CAAC"}
|
|
@@ -2025,6 +2025,14 @@ async function collectDomTargetsFromDocument(context, options) {
|
|
|
2025
2025
|
}
|
|
2026
2026
|
}
|
|
2027
2027
|
|
|
2028
|
+
return undefined;
|
|
2029
|
+
};
|
|
2030
|
+
|
|
2031
|
+
const contextTextOf = (element) => {
|
|
2032
|
+
if (!isHTMLElementNode(element)) {
|
|
2033
|
+
return undefined;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2028
2036
|
const text = textOf(element, { container: true });
|
|
2029
2037
|
if (!text) {
|
|
2030
2038
|
return undefined;
|
|
@@ -2036,14 +2044,19 @@ async function collectDomTargetsFromDocument(context, options) {
|
|
|
2036
2044
|
if (!element) return undefined;
|
|
2037
2045
|
|
|
2038
2046
|
const kind = element.getAttribute?.('role')?.trim() || element.tagName?.toLowerCase?.();
|
|
2039
|
-
const
|
|
2047
|
+
const fallbackLabel = contextLabelOf(element);
|
|
2048
|
+
const text = contextTextOf(element);
|
|
2040
2049
|
const selector = buildSelector(element);
|
|
2041
|
-
if (!kind && !
|
|
2050
|
+
if (!kind && !fallbackLabel && !text && !selector) return undefined;
|
|
2042
2051
|
return {
|
|
2043
2052
|
kind: kind || undefined,
|
|
2044
|
-
label,
|
|
2045
|
-
text:
|
|
2053
|
+
label: undefined,
|
|
2054
|
+
text:
|
|
2055
|
+
text && (!fallbackLabel || text.toLowerCase() !== fallbackLabel.toLowerCase())
|
|
2056
|
+
? text
|
|
2057
|
+
: undefined,
|
|
2046
2058
|
selector,
|
|
2059
|
+
fallbackLabel,
|
|
2047
2060
|
};
|
|
2048
2061
|
};
|
|
2049
2062
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type SemanticObserveAnalyzerKey = 'en' | 'ru' | 'neutral';
|
|
2
|
+
export type SemanticObserveLexicalField = {
|
|
3
|
+
value?: string;
|
|
4
|
+
weight: number;
|
|
5
|
+
};
|
|
6
|
+
export type SemanticObserveAnalyzedText = {
|
|
7
|
+
analyzerKey: SemanticObserveAnalyzerKey;
|
|
8
|
+
normalizedText?: string;
|
|
9
|
+
terms: string[];
|
|
10
|
+
};
|
|
11
|
+
export type SemanticObserveLexicalDocument = {
|
|
12
|
+
analyzerKey: SemanticObserveAnalyzerKey;
|
|
13
|
+
weightedLength: number;
|
|
14
|
+
weightedTermFrequencies: Map<string, number>;
|
|
15
|
+
};
|
|
16
|
+
export type SemanticObserveBm25CorpusStats = {
|
|
17
|
+
averageDocumentLength: number;
|
|
18
|
+
documentCount: number;
|
|
19
|
+
documentFrequencyByTerm: Map<string, number>;
|
|
20
|
+
};
|
|
21
|
+
export declare function assertSemanticObserveRuntimeSupport(): void;
|
|
22
|
+
export declare function normalizeSemanticObserveText(value: string | undefined): string | undefined;
|
|
23
|
+
export declare function dominantSemanticObserveAnalyzerKey(value: string | undefined): SemanticObserveAnalyzerKey;
|
|
24
|
+
export declare function analyzeSemanticObserveText(value: string | undefined): SemanticObserveAnalyzedText;
|
|
25
|
+
export declare function buildSemanticObserveLexicalDocument(fields: ReadonlyArray<SemanticObserveLexicalField>): SemanticObserveLexicalDocument;
|
|
26
|
+
export declare function buildSemanticObserveBm25CorpusStats(documents: ReadonlyArray<SemanticObserveLexicalDocument>): SemanticObserveBm25CorpusStats;
|
|
27
|
+
export declare function scoreSemanticObserveBm25(query: SemanticObserveAnalyzedText, document: SemanticObserveLexicalDocument, corpus: SemanticObserveBm25CorpusStats, options?: {
|
|
28
|
+
k1?: number;
|
|
29
|
+
b?: number;
|
|
30
|
+
}): number;
|
|
31
|
+
//# sourceMappingURL=semantic-observe-lexical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-observe-lexical.d.ts","sourceRoot":"","sources":["../../src/commands/semantic-observe-lexical.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,0BAA0B,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;AAEjE,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,0BAA0B,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,WAAW,EAAE,0BAA0B,CAAC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC;AAMF,wBAAgB,mCAAmC,IAAI,IAAI,CAM1D;AAgDD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAO1F;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,0BAA0B,CAwB5B;AAmCD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,2BAA2B,CAqBjG;AAED,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,aAAa,CAAC,2BAA2B,CAAC,GACjD,8BAA8B,CAoChC;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,aAAa,CAAC,8BAA8B,CAAC,GACvD,8BAA8B,CAiBhC;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,2BAA2B,EAClC,QAAQ,EAAE,8BAA8B,EACxC,MAAM,EAAE,8BAA8B,EACtC,OAAO,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,MAAM,CA0BR"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { newStemmer } from 'snowball-stemmers';
|
|
2
|
+
const TOKENIZER_FALLBACK_RE = /[\p{L}\p{N}]+/gu;
|
|
3
|
+
const segmenterCache = new Map();
|
|
4
|
+
const stemmerCache = new Map();
|
|
5
|
+
export function assertSemanticObserveRuntimeSupport() {
|
|
6
|
+
if (typeof Intl === 'undefined' || typeof Intl.Segmenter !== 'function') {
|
|
7
|
+
throw new Error('AgentBrowse requires Intl.Segmenter. Use a modern Node runtime with standard Intl support.');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function segmenterFor(locale) {
|
|
11
|
+
const cached = segmenterCache.get(locale);
|
|
12
|
+
if (cached !== undefined) {
|
|
13
|
+
return cached;
|
|
14
|
+
}
|
|
15
|
+
assertSemanticObserveRuntimeSupport();
|
|
16
|
+
const segmenter = new Intl.Segmenter(locale === 'neutral' ? undefined : locale, {
|
|
17
|
+
granularity: 'word',
|
|
18
|
+
});
|
|
19
|
+
segmenterCache.set(locale, segmenter);
|
|
20
|
+
return segmenter;
|
|
21
|
+
}
|
|
22
|
+
function stemmerFor(locale) {
|
|
23
|
+
const cached = stemmerCache.get(locale);
|
|
24
|
+
if (cached !== undefined) {
|
|
25
|
+
return cached;
|
|
26
|
+
}
|
|
27
|
+
const algorithm = locale === 'en' ? 'english' : locale === 'ru' ? 'russian' : undefined;
|
|
28
|
+
if (!algorithm) {
|
|
29
|
+
stemmerCache.set(locale, null);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const stemmer = newStemmer(algorithm);
|
|
33
|
+
stemmerCache.set(locale, stemmer);
|
|
34
|
+
return stemmer;
|
|
35
|
+
}
|
|
36
|
+
function isNumericToken(token) {
|
|
37
|
+
return /^[\p{N}]+$/u.test(token);
|
|
38
|
+
}
|
|
39
|
+
function detectAnalyzerKeyForToken(token) {
|
|
40
|
+
if (/[\p{Script=Cyrillic}]/u.test(token)) {
|
|
41
|
+
return 'ru';
|
|
42
|
+
}
|
|
43
|
+
if (/[\p{Script=Latin}]/u.test(token)) {
|
|
44
|
+
return 'en';
|
|
45
|
+
}
|
|
46
|
+
return 'neutral';
|
|
47
|
+
}
|
|
48
|
+
export function normalizeSemanticObserveText(value) {
|
|
49
|
+
const normalized = value
|
|
50
|
+
?.normalize('NFKC')
|
|
51
|
+
.replace(/\s+/g, ' ')
|
|
52
|
+
.trim()
|
|
53
|
+
.toLowerCase();
|
|
54
|
+
return normalized ? normalized : undefined;
|
|
55
|
+
}
|
|
56
|
+
export function dominantSemanticObserveAnalyzerKey(value) {
|
|
57
|
+
const normalized = normalizeSemanticObserveText(value);
|
|
58
|
+
if (!normalized) {
|
|
59
|
+
return 'neutral';
|
|
60
|
+
}
|
|
61
|
+
let latinCount = 0;
|
|
62
|
+
let cyrillicCount = 0;
|
|
63
|
+
for (const token of normalized.match(TOKENIZER_FALLBACK_RE) ?? []) {
|
|
64
|
+
const key = detectAnalyzerKeyForToken(token);
|
|
65
|
+
if (key === 'en') {
|
|
66
|
+
latinCount += 1;
|
|
67
|
+
}
|
|
68
|
+
else if (key === 'ru') {
|
|
69
|
+
cyrillicCount += 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (cyrillicCount > latinCount) {
|
|
73
|
+
return 'ru';
|
|
74
|
+
}
|
|
75
|
+
if (latinCount > 0) {
|
|
76
|
+
return 'en';
|
|
77
|
+
}
|
|
78
|
+
return 'neutral';
|
|
79
|
+
}
|
|
80
|
+
function segmentSemanticObserveText(normalizedText, locale) {
|
|
81
|
+
const segmenter = segmenterFor(locale);
|
|
82
|
+
const tokens = [];
|
|
83
|
+
for (const segment of segmenter.segment(normalizedText)) {
|
|
84
|
+
if (segment.isWordLike === false) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const token = normalizeSemanticObserveText(segment.segment);
|
|
88
|
+
if (!token) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (!/[\p{L}\p{N}]/u.test(token)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
tokens.push(token);
|
|
95
|
+
}
|
|
96
|
+
return tokens;
|
|
97
|
+
}
|
|
98
|
+
function stemSemanticObserveToken(token) {
|
|
99
|
+
const analyzerKey = detectAnalyzerKeyForToken(token);
|
|
100
|
+
const stemmer = stemmerFor(analyzerKey);
|
|
101
|
+
if (!stemmer) {
|
|
102
|
+
return token;
|
|
103
|
+
}
|
|
104
|
+
const stemmed = normalizeSemanticObserveText(stemmer.stem(token));
|
|
105
|
+
return stemmed && (stemmed.length >= 2 || isNumericToken(stemmed)) ? stemmed : token;
|
|
106
|
+
}
|
|
107
|
+
export function analyzeSemanticObserveText(value) {
|
|
108
|
+
const normalizedText = normalizeSemanticObserveText(value);
|
|
109
|
+
if (!normalizedText) {
|
|
110
|
+
return {
|
|
111
|
+
analyzerKey: 'neutral',
|
|
112
|
+
normalizedText: undefined,
|
|
113
|
+
terms: [],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const analyzerKey = dominantSemanticObserveAnalyzerKey(normalizedText);
|
|
117
|
+
const segmented = segmentSemanticObserveText(normalizedText, analyzerKey);
|
|
118
|
+
const terms = segmented
|
|
119
|
+
.map((token) => stemSemanticObserveToken(token))
|
|
120
|
+
.filter((token) => token.length >= 2 || isNumericToken(token));
|
|
121
|
+
return {
|
|
122
|
+
analyzerKey,
|
|
123
|
+
normalizedText,
|
|
124
|
+
terms,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export function buildSemanticObserveLexicalDocument(fields) {
|
|
128
|
+
const weightedTermFrequencies = new Map();
|
|
129
|
+
const analyzerVotes = new Map();
|
|
130
|
+
let weightedLength = 0;
|
|
131
|
+
for (const field of fields) {
|
|
132
|
+
if (field.weight <= 0) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const analyzed = analyzeSemanticObserveText(field.value);
|
|
136
|
+
if (analyzed.terms.length === 0) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
analyzerVotes.set(analyzed.analyzerKey, (analyzerVotes.get(analyzed.analyzerKey) ?? 0) + analyzed.terms.length);
|
|
140
|
+
weightedLength += analyzed.terms.length * field.weight;
|
|
141
|
+
for (const term of analyzed.terms) {
|
|
142
|
+
weightedTermFrequencies.set(term, (weightedTermFrequencies.get(term) ?? 0) + field.weight);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const analyzerKey = [...analyzerVotes.entries()].sort((left, right) => right[1] - left[1])[0]?.[0] ?? 'neutral';
|
|
146
|
+
return {
|
|
147
|
+
analyzerKey,
|
|
148
|
+
weightedLength,
|
|
149
|
+
weightedTermFrequencies,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
export function buildSemanticObserveBm25CorpusStats(documents) {
|
|
153
|
+
const documentFrequencyByTerm = new Map();
|
|
154
|
+
let totalLength = 0;
|
|
155
|
+
for (const document of documents) {
|
|
156
|
+
totalLength += document.weightedLength;
|
|
157
|
+
for (const term of document.weightedTermFrequencies.keys()) {
|
|
158
|
+
documentFrequencyByTerm.set(term, (documentFrequencyByTerm.get(term) ?? 0) + 1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
averageDocumentLength: documents.length > 0 ? totalLength / documents.length : 0,
|
|
163
|
+
documentCount: documents.length,
|
|
164
|
+
documentFrequencyByTerm,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
export function scoreSemanticObserveBm25(query, document, corpus, options = {}) {
|
|
168
|
+
if (query.terms.length === 0 || document.weightedTermFrequencies.size === 0 || corpus.documentCount === 0) {
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
const k1 = options.k1 ?? 1.2;
|
|
172
|
+
const b = options.b ?? 0.75;
|
|
173
|
+
const averageDocumentLength = Math.max(corpus.averageDocumentLength, 1);
|
|
174
|
+
const documentLength = Math.max(document.weightedLength, 1);
|
|
175
|
+
const uniqueTerms = [...new Set(query.terms)];
|
|
176
|
+
let score = 0;
|
|
177
|
+
for (const term of uniqueTerms) {
|
|
178
|
+
const termFrequency = document.weightedTermFrequencies.get(term) ?? 0;
|
|
179
|
+
if (termFrequency <= 0) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const documentFrequency = corpus.documentFrequencyByTerm.get(term) ?? 0;
|
|
183
|
+
const idf = Math.log(1 + (corpus.documentCount - documentFrequency + 0.5) / (documentFrequency + 0.5));
|
|
184
|
+
const denominator = termFrequency + k1 * (1 - b + b * (documentLength / averageDocumentLength));
|
|
185
|
+
score += idf * ((termFrequency * (k1 + 1)) / denominator);
|
|
186
|
+
}
|
|
187
|
+
return score;
|
|
188
|
+
}
|
|
@@ -24,6 +24,7 @@ type ObserveInventoryTarget = {
|
|
|
24
24
|
pageSignature?: string;
|
|
25
25
|
goalInventoryType?: 'target' | 'scope';
|
|
26
26
|
goalSurfaceId?: string;
|
|
27
|
+
controlsSurfaceSelector?: string;
|
|
27
28
|
};
|
|
28
29
|
export declare function rerankDomTargetsForGoal<T extends ObserveInventoryTarget>(instruction: string, targets: ReadonlyArray<T>, options?: {
|
|
29
30
|
session?: BrowseSession;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-observe.d.ts","sourceRoot":"","sources":["../../src/commands/semantic-observe.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,eAAe,EAChB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"semantic-observe.d.ts","sourceRoot":"","sources":["../../src/commands/semantic-observe.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAY7B,KAAK,sBAAsB,GAAG;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACvC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAwoCF,wBAAsB,uBAAuB,CAAC,CAAC,SAAS,sBAAsB,EAC5E,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EACzB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,aAAa,CAAA;CAAO,GACxC,OAAO,CAAC,CAAC,EAAE,CAAC,CA2Ed"}
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { AgentpayStagehandLlmClient } from '../agentpay-stagehand-llm.js';
|
|
3
3
|
import { resolveAgentpayGatewayConfig } from '../agentpay-gateway.js';
|
|
4
4
|
import { recordLlmUsage, recordPayloadBudget } from '../runtime-state.js';
|
|
5
|
+
import { analyzeSemanticObserveText, buildSemanticObserveBm25CorpusStats, buildSemanticObserveLexicalDocument, normalizeSemanticObserveText, scoreSemanticObserveBm25, } from './semantic-observe-lexical.js';
|
|
5
6
|
const rerankSchema = z.object({
|
|
6
7
|
matches: z
|
|
7
8
|
.array(z.object({
|
|
@@ -17,6 +18,31 @@ const SCOPE_BUCKET_RESERVE_LIMIT = 24;
|
|
|
17
18
|
const SCOPE_BUCKET_RESERVE_PER_BUCKET = 2;
|
|
18
19
|
const IFRAME_BUCKET_RESERVE_LIMIT = 24;
|
|
19
20
|
const IFRAME_BUCKET_RESERVE_PER_BUCKET = 2;
|
|
21
|
+
const RETRIEVAL_FIELD_WEIGHTS = {
|
|
22
|
+
entityLabel: 5.5,
|
|
23
|
+
representativeLabel: 5,
|
|
24
|
+
representativeLabels: 4,
|
|
25
|
+
surfaceLabel: 2.25,
|
|
26
|
+
placeholder: 2.5,
|
|
27
|
+
title: 1.25,
|
|
28
|
+
itemLabel: 2.5,
|
|
29
|
+
itemText: 1.5,
|
|
30
|
+
groupLabel: 1.75,
|
|
31
|
+
groupText: 1,
|
|
32
|
+
containerLabel: 1.5,
|
|
33
|
+
containerText: 0.9,
|
|
34
|
+
landmarkLabel: 1.25,
|
|
35
|
+
landmarkText: 0.75,
|
|
36
|
+
hintText: 1.5,
|
|
37
|
+
kind: 0.6,
|
|
38
|
+
role: 0.6,
|
|
39
|
+
surfaceKind: 0.75,
|
|
40
|
+
controlFamily: 0.9,
|
|
41
|
+
acceptancePolicy: 1,
|
|
42
|
+
allowedActions: 0.9,
|
|
43
|
+
structure: 1.25,
|
|
44
|
+
latentIntent: 1.2,
|
|
45
|
+
};
|
|
20
46
|
const HIGH_SIGNAL_SCOPE_KINDS = new Set([
|
|
21
47
|
'dialog',
|
|
22
48
|
'listbox',
|
|
@@ -29,27 +55,6 @@ const HIGH_SIGNAL_SCOPE_KINDS = new Set([
|
|
|
29
55
|
'card',
|
|
30
56
|
'form',
|
|
31
57
|
]);
|
|
32
|
-
const GOAL_TEXT_STOPWORDS = new Set([
|
|
33
|
-
'a',
|
|
34
|
-
'an',
|
|
35
|
-
'and',
|
|
36
|
-
'at',
|
|
37
|
-
'for',
|
|
38
|
-
'from',
|
|
39
|
-
'in',
|
|
40
|
-
'of',
|
|
41
|
-
'on',
|
|
42
|
-
'or',
|
|
43
|
-
'the',
|
|
44
|
-
'to',
|
|
45
|
-
'with',
|
|
46
|
-
'в',
|
|
47
|
-
'для',
|
|
48
|
-
'и',
|
|
49
|
-
'или',
|
|
50
|
-
'на',
|
|
51
|
-
'найти',
|
|
52
|
-
]);
|
|
53
58
|
function isFieldLikeTarget(target) {
|
|
54
59
|
const kind = (target.kind ?? '').trim().toLowerCase();
|
|
55
60
|
const role = (target.role ?? '').trim().toLowerCase();
|
|
@@ -73,16 +78,6 @@ function isActionLikeTargetCandidate(target) {
|
|
|
73
78
|
kind === 'link' ||
|
|
74
79
|
role === 'link');
|
|
75
80
|
}
|
|
76
|
-
function normalizeRetrievalText(value) {
|
|
77
|
-
const normalized = value?.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
78
|
-
return normalized ? normalized : undefined;
|
|
79
|
-
}
|
|
80
|
-
function tokenizeRetrievalText(value) {
|
|
81
|
-
if (!value) {
|
|
82
|
-
return [];
|
|
83
|
-
}
|
|
84
|
-
return (value.match(/[\p{L}\p{N}]+/gu) ?? []).map((token) => token.toLowerCase());
|
|
85
|
-
}
|
|
86
81
|
function semanticFormContextKey(context) {
|
|
87
82
|
for (const node of [context?.landmark, context?.container, context?.group, context?.item]) {
|
|
88
83
|
const kind = (node?.kind ?? '').trim().toLowerCase();
|
|
@@ -140,6 +135,13 @@ function isPrimaryFormControlTarget(target) {
|
|
|
140
135
|
acceptancePolicy === 'disclosure' &&
|
|
141
136
|
(kind === 'button' || role === 'button'));
|
|
142
137
|
}
|
|
138
|
+
function shouldPreserveStandaloneFormActionEntity(target) {
|
|
139
|
+
return (Boolean(formBucketKey(target)) &&
|
|
140
|
+
!isScopeLikeCandidate(target) &&
|
|
141
|
+
!isFieldLikeTarget(target) &&
|
|
142
|
+
isActionLikeTargetCandidate(target) &&
|
|
143
|
+
isPrimaryFormControlTarget(target));
|
|
144
|
+
}
|
|
143
145
|
function primaryFormTargetPriority(target) {
|
|
144
146
|
const acceptancePolicy = (target.acceptancePolicy ?? '').trim().toLowerCase();
|
|
145
147
|
if (isFieldLikeTarget(target)) {
|
|
@@ -178,11 +180,11 @@ function contentItemBucketKey(target) {
|
|
|
178
180
|
if (surfaceIdentity) {
|
|
179
181
|
return `surface:${surfaceIdentity}`;
|
|
180
182
|
}
|
|
181
|
-
const itemKey =
|
|
183
|
+
const itemKey = normalizeSemanticObserveText(target.context?.item?.label ?? target.context?.item?.text);
|
|
182
184
|
if (itemKey) {
|
|
183
185
|
return `item:${itemKey}`;
|
|
184
186
|
}
|
|
185
|
-
const containerKey =
|
|
187
|
+
const containerKey = normalizeSemanticObserveText(target.context?.container?.label ?? target.context?.container?.text);
|
|
186
188
|
if (containerKey) {
|
|
187
189
|
return `container:${containerKey}`;
|
|
188
190
|
}
|
|
@@ -205,7 +207,7 @@ function scopeCandidatePriority(target) {
|
|
|
205
207
|
return 4;
|
|
206
208
|
}
|
|
207
209
|
function representativeCandidateScore(target) {
|
|
208
|
-
const normalizedLabel =
|
|
210
|
+
const normalizedLabel = normalizeSemanticObserveText(target.label);
|
|
209
211
|
const kind = (target.kind ?? '').trim().toLowerCase();
|
|
210
212
|
const role = (target.role ?? '').trim().toLowerCase();
|
|
211
213
|
let score = (target.surfacePriority ?? 0) * 10;
|
|
@@ -295,26 +297,131 @@ function collectRepresentativeLabels(targets) {
|
|
|
295
297
|
}
|
|
296
298
|
return labels;
|
|
297
299
|
}
|
|
298
|
-
function
|
|
300
|
+
function structureLexicalValue(structure) {
|
|
301
|
+
if (!structure) {
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
299
304
|
return [
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
representative.context?.group?.label,
|
|
307
|
-
representative.context?.group?.text,
|
|
308
|
-
representative.context?.container?.label,
|
|
309
|
-
representative.context?.container?.text,
|
|
310
|
-
representative.context?.landmark?.label,
|
|
311
|
-
representative.context?.landmark?.text,
|
|
312
|
-
representative.context?.hintText,
|
|
305
|
+
structure.family,
|
|
306
|
+
structure.variant,
|
|
307
|
+
structure.row,
|
|
308
|
+
structure.column,
|
|
309
|
+
structure.zone,
|
|
310
|
+
structure.cellLabel,
|
|
313
311
|
]
|
|
314
|
-
.
|
|
315
|
-
.filter((value) => Boolean(value))
|
|
312
|
+
.filter(Boolean)
|
|
316
313
|
.join(' ');
|
|
317
314
|
}
|
|
315
|
+
function latentActionHintText(target) {
|
|
316
|
+
const acceptancePolicy = (target.acceptancePolicy ?? '').trim().toLowerCase();
|
|
317
|
+
const controlFamily = (target.controlFamily ?? '').trim().toLowerCase();
|
|
318
|
+
const surfaceKind = (target.surfaceKind ?? '').trim().toLowerCase();
|
|
319
|
+
const kind = (target.kind ?? '').trim().toLowerCase();
|
|
320
|
+
const role = (target.role ?? '').trim().toLowerCase();
|
|
321
|
+
const popupBacked = acceptancePolicy === 'disclosure' ||
|
|
322
|
+
Boolean(target.controlsSurfaceSelector) ||
|
|
323
|
+
target.states?.expanded !== undefined;
|
|
324
|
+
if (!popupBacked) {
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
const hints = new Set();
|
|
328
|
+
hints.add('open menu options choices');
|
|
329
|
+
if (!isFieldLikeTarget(target)) {
|
|
330
|
+
hints.add('sort sorting filter filters view switch picker');
|
|
331
|
+
}
|
|
332
|
+
if (controlFamily === 'select' ||
|
|
333
|
+
['menu', 'listbox', 'dropdown', 'popover'].includes(surfaceKind)) {
|
|
334
|
+
hints.add('select choose option options menu dropdown listbox');
|
|
335
|
+
}
|
|
336
|
+
if (controlFamily === 'datepicker' || surfaceKind === 'datepicker') {
|
|
337
|
+
hints.add('open calendar datepicker date picker choose date calendar');
|
|
338
|
+
}
|
|
339
|
+
const evidenceText = [
|
|
340
|
+
target.label,
|
|
341
|
+
target.placeholder,
|
|
342
|
+
target.title,
|
|
343
|
+
target.surfaceLabel,
|
|
344
|
+
target.context?.group?.label,
|
|
345
|
+
target.context?.container?.label,
|
|
346
|
+
target.context?.landmark?.label,
|
|
347
|
+
target.context?.hintText,
|
|
348
|
+
]
|
|
349
|
+
.filter((value) => Boolean(value))
|
|
350
|
+
.join(' ')
|
|
351
|
+
.toLowerCase();
|
|
352
|
+
if (/(?:sort|sorting|show first|ordered by|order by|popular|relevance|recommended|price|cheap|cheapest|expensive|сорт|сначала|популяр|релевант|рекоменд|цене|дешев|дорог)/i.test(evidenceText)) {
|
|
353
|
+
hints.add('sort sorting order order by relevance popular recommended price cheapest cheapest first');
|
|
354
|
+
}
|
|
355
|
+
if (/(?:filter|filters|refine|brand|airline|amenit|фильтр|фильтры|бренд|авиакомпан|удобств)/i.test(evidenceText)) {
|
|
356
|
+
hints.add('filter filters refine refine results brand airline amenities');
|
|
357
|
+
}
|
|
358
|
+
if (/(?:view|layout|grid|list|map|calendar view|вид|список|сетка|карта|раскладк)/i.test(evidenceText)) {
|
|
359
|
+
hints.add('view layout grid list map switch');
|
|
360
|
+
}
|
|
361
|
+
if (kind === 'button' &&
|
|
362
|
+
role === 'button' &&
|
|
363
|
+
(acceptancePolicy === 'disclosure' || controlFamily === 'select' || controlFamily === 'datepicker')) {
|
|
364
|
+
hints.add('open selector choose mode');
|
|
365
|
+
}
|
|
366
|
+
return hints.size > 0 ? [...hints].join(' ') : undefined;
|
|
367
|
+
}
|
|
368
|
+
function buildEntityLexicalFields(entityLabel, representative, representativeLabels) {
|
|
369
|
+
return [
|
|
370
|
+
{ value: entityLabel, weight: RETRIEVAL_FIELD_WEIGHTS.entityLabel },
|
|
371
|
+
{ value: representative.label, weight: RETRIEVAL_FIELD_WEIGHTS.representativeLabel },
|
|
372
|
+
...representativeLabels.map((value) => ({
|
|
373
|
+
value,
|
|
374
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.representativeLabels,
|
|
375
|
+
})),
|
|
376
|
+
{ value: representative.surfaceLabel, weight: RETRIEVAL_FIELD_WEIGHTS.surfaceLabel },
|
|
377
|
+
{ value: representative.placeholder, weight: RETRIEVAL_FIELD_WEIGHTS.placeholder },
|
|
378
|
+
{ value: representative.title, weight: RETRIEVAL_FIELD_WEIGHTS.title },
|
|
379
|
+
{ value: representative.context?.item?.label, weight: RETRIEVAL_FIELD_WEIGHTS.itemLabel },
|
|
380
|
+
{ value: representative.context?.item?.text, weight: RETRIEVAL_FIELD_WEIGHTS.itemText },
|
|
381
|
+
{ value: representative.context?.group?.label, weight: RETRIEVAL_FIELD_WEIGHTS.groupLabel },
|
|
382
|
+
{ value: representative.context?.group?.text, weight: RETRIEVAL_FIELD_WEIGHTS.groupText },
|
|
383
|
+
{
|
|
384
|
+
value: representative.context?.container?.label,
|
|
385
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.containerLabel,
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
value: representative.context?.container?.text,
|
|
389
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.containerText,
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
value: representative.context?.landmark?.label,
|
|
393
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.landmarkLabel,
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
value: representative.context?.landmark?.text,
|
|
397
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.landmarkText,
|
|
398
|
+
},
|
|
399
|
+
{ value: representative.context?.hintText, weight: RETRIEVAL_FIELD_WEIGHTS.hintText },
|
|
400
|
+
{ value: representative.kind, weight: RETRIEVAL_FIELD_WEIGHTS.kind },
|
|
401
|
+
{ value: representative.role, weight: RETRIEVAL_FIELD_WEIGHTS.role },
|
|
402
|
+
{ value: representative.surfaceKind, weight: RETRIEVAL_FIELD_WEIGHTS.surfaceKind },
|
|
403
|
+
{
|
|
404
|
+
value: representative.controlFamily,
|
|
405
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.controlFamily,
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
value: representative.acceptancePolicy,
|
|
409
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.acceptancePolicy,
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
value: representative.allowedActions?.join(' '),
|
|
413
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.allowedActions,
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
value: structureLexicalValue(representative.structure),
|
|
417
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.structure,
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
value: latentActionHintText(representative),
|
|
421
|
+
weight: RETRIEVAL_FIELD_WEIGHTS.latentIntent,
|
|
422
|
+
},
|
|
423
|
+
];
|
|
424
|
+
}
|
|
318
425
|
function buildGoalRetrievalEntity(entityKind, entityKey, memberIndexes, targets) {
|
|
319
426
|
const orderedMembers = [...memberIndexes]
|
|
320
427
|
.map((index) => ({ index, target: targets[index] }))
|
|
@@ -322,6 +429,8 @@ function buildGoalRetrievalEntity(entityKind, entityKey, memberIndexes, targets)
|
|
|
322
429
|
const representative = orderedMembers[0].target;
|
|
323
430
|
const representativeLabels = collectRepresentativeLabels(orderedMembers.map((entry) => entry.target));
|
|
324
431
|
const label = pickEntityLabel(entityKind, representative);
|
|
432
|
+
const lexicalFields = buildEntityLexicalFields(label, representative, representativeLabels);
|
|
433
|
+
const lexicalDocument = buildSemanticObserveLexicalDocument(lexicalFields);
|
|
325
434
|
return {
|
|
326
435
|
entityKind,
|
|
327
436
|
entityKey,
|
|
@@ -342,7 +451,8 @@ function buildGoalRetrievalEntity(entityKind, entityKey, memberIndexes, targets)
|
|
|
342
451
|
context: representative.context,
|
|
343
452
|
structure: representative.structure,
|
|
344
453
|
representativeLabels,
|
|
345
|
-
|
|
454
|
+
analyzerKey: lexicalDocument.analyzerKey,
|
|
455
|
+
lexicalDocument,
|
|
346
456
|
};
|
|
347
457
|
}
|
|
348
458
|
function buildGoalRetrievalEntities(targets) {
|
|
@@ -376,7 +486,12 @@ function buildGoalRetrievalEntities(targets) {
|
|
|
376
486
|
}
|
|
377
487
|
for (const [key, memberIndexes] of formGroups.entries()) {
|
|
378
488
|
entities.push(buildGoalRetrievalEntity('form', `form:${key}`, memberIndexes, targets));
|
|
379
|
-
memberIndexes.forEach((index) =>
|
|
489
|
+
memberIndexes.forEach((index) => {
|
|
490
|
+
if (shouldPreserveStandaloneFormActionEntity(targets[index])) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
groupedTargetIndexes.add(index);
|
|
494
|
+
});
|
|
380
495
|
}
|
|
381
496
|
const itemGroups = new Map();
|
|
382
497
|
for (const [index, target] of targets.entries()) {
|
|
@@ -445,58 +560,28 @@ function retrievalEntityPriority(entity) {
|
|
|
445
560
|
score += representativeCandidateScore(entity.representative);
|
|
446
561
|
return score;
|
|
447
562
|
}
|
|
448
|
-
function scoreRetrievalEntityAgainstGoal(
|
|
449
|
-
|
|
450
|
-
if (!normalizedGoal) {
|
|
563
|
+
function scoreRetrievalEntityAgainstGoal(analyzedGoal, entity, corpusStats) {
|
|
564
|
+
if (!analyzedGoal.normalizedText) {
|
|
451
565
|
return 0;
|
|
452
566
|
}
|
|
453
|
-
|
|
454
|
-
if (!entityText) {
|
|
567
|
+
if (entity.lexicalDocument.weightedLength <= 0) {
|
|
455
568
|
return 0;
|
|
456
569
|
}
|
|
457
|
-
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
const entityLabel = normalizeRetrievalText(entity.label);
|
|
464
|
-
if (entityLabel) {
|
|
465
|
-
if (normalizedGoal.includes(entityLabel)) {
|
|
466
|
-
score += 180;
|
|
467
|
-
}
|
|
468
|
-
if (entityLabel.includes(normalizedGoal)) {
|
|
469
|
-
score += 140;
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
let matchedTokenCount = 0;
|
|
473
|
-
for (const token of goalTokens) {
|
|
474
|
-
if (entityTokens.has(token)) {
|
|
475
|
-
matchedTokenCount += 1;
|
|
476
|
-
score += 8 + Math.min(token.length, 12);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
if (goalTokens.length > 0) {
|
|
480
|
-
const coverage = matchedTokenCount / goalTokens.length;
|
|
481
|
-
if (coverage === 1) {
|
|
482
|
-
score += 120;
|
|
483
|
-
}
|
|
484
|
-
else if (coverage >= 0.75) {
|
|
485
|
-
score += 70;
|
|
486
|
-
}
|
|
487
|
-
else if (coverage >= 0.5) {
|
|
488
|
-
score += 35;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
return score;
|
|
570
|
+
const bm25Score = scoreSemanticObserveBm25(analyzedGoal, entity.lexicalDocument, corpusStats);
|
|
571
|
+
const analyzerAlignmentScore = analyzedGoal.analyzerKey !== 'neutral' && analyzedGoal.analyzerKey === entity.analyzerKey
|
|
572
|
+
? 15
|
|
573
|
+
: 0;
|
|
574
|
+
return bm25Score * 100 + analyzerAlignmentScore;
|
|
492
575
|
}
|
|
493
576
|
function preselectRetrievalEntities(goal, entities) {
|
|
494
577
|
if (entities.length <= GOAL_RETRIEVAL_ENTITY_LIMIT) {
|
|
495
578
|
return [...entities];
|
|
496
579
|
}
|
|
580
|
+
const analyzedGoal = analyzeSemanticObserveText(goal);
|
|
581
|
+
const corpusStats = buildSemanticObserveBm25CorpusStats(entities.map((entity) => entity.lexicalDocument));
|
|
497
582
|
const scored = entities.map((entity) => ({
|
|
498
583
|
entity,
|
|
499
|
-
lexicalScore: scoreRetrievalEntityAgainstGoal(
|
|
584
|
+
lexicalScore: scoreRetrievalEntityAgainstGoal(analyzedGoal, entity, corpusStats),
|
|
500
585
|
priority: retrievalEntityPriority(entity),
|
|
501
586
|
}));
|
|
502
587
|
const selected = [];
|
|
@@ -634,9 +719,6 @@ function diversifyCandidates(targets) {
|
|
|
634
719
|
}
|
|
635
720
|
return orderedIndexes.map((index) => targets[index]).slice(0, RERANK_CANDIDATE_LIMIT);
|
|
636
721
|
}
|
|
637
|
-
function buildCandidateSummary(target, index, surfaceSummaryIdBySurfaceKey) {
|
|
638
|
-
return buildCompactCandidateSummary(target, index, surfaceSummaryIdBySurfaceKey);
|
|
639
|
-
}
|
|
640
722
|
function compactContextValue(value, maxLength = 80) {
|
|
641
723
|
const normalized = value?.replace(/\s+/g, ' ').trim();
|
|
642
724
|
if (!normalized) {
|
|
@@ -791,6 +873,9 @@ function buildCompactCandidateSummary(target, index, surfaceSummaryIdBySurfaceKe
|
|
|
791
873
|
if (target.controlFamily) {
|
|
792
874
|
parts.push(`family=${JSON.stringify(target.controlFamily)}`);
|
|
793
875
|
}
|
|
876
|
+
if (target.controlsSurfaceSelector) {
|
|
877
|
+
parts.push('controlsPopup=true');
|
|
878
|
+
}
|
|
794
879
|
if (target.capability && target.capability !== 'actionable') {
|
|
795
880
|
parts.push(`capability=${JSON.stringify(target.capability)}`);
|
|
796
881
|
}
|
|
@@ -836,6 +921,7 @@ export async function rerankDomTargetsForGoal(instruction, targets, options = {}
|
|
|
836
921
|
const prompt = [
|
|
837
922
|
'You are choosing from already discovered visible webpage candidates.',
|
|
838
923
|
'Select only candidate IDs that directly satisfy the goal.',
|
|
924
|
+
'A disclosure trigger with a current-state label can still directly satisfy sort, filter, view-switch, or picker goals when opening it is the immediate next step.',
|
|
839
925
|
'Prefer direct actionable controls over surrounding regions unless the goal explicitly asks for a form, region, widget, or set of controls.',
|
|
840
926
|
'Use owning surface, compact context, explicit state, and structure metadata to disambiguate similar labels.',
|
|
841
927
|
'For input/value goals, prefer the directly editable field or primary picker trigger over wrappers or mirrored summary content.',
|
|
@@ -847,7 +933,7 @@ export async function rerankDomTargetsForGoal(instruction, targets, options = {}
|
|
|
847
933
|
'',
|
|
848
934
|
...(surfaceSummaries.length > 0 ? ['Surfaces:', ...surfaceSummaries.map((entry) => entry.line), ''] : []),
|
|
849
935
|
'Candidates:',
|
|
850
|
-
...candidates.map((target, index) =>
|
|
936
|
+
...candidates.map((target, index) => buildCompactCandidateSummary(target, index, summaryIdBySurfaceKey)),
|
|
851
937
|
].join('\n');
|
|
852
938
|
const result = await client.createChatCompletion({
|
|
853
939
|
logger: () => { },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-semantics.d.ts","sourceRoot":"","sources":["../src/control-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"control-semantics.d.ts","sourceRoot":"","sources":["../src/control-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAiDtF,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,oBAAoB,GAC1B,mBAAmB,GAAG,SAAS,CAuCjC;AA2ID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAYxE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,oBAAoB,GAAG,mBAAmB,EAAE,CAoG/F;AAED,wBAAgB,0BAA0B,CACxC,MAAM,CAAC,EAAE,gBAAgB,EACzB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B,GACL,uBAAuB,CAyBzB;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,mBAAmB,GAAG,SAAS,CA0EjC;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,sBAAsB,GAAG,SAAS,CA6CpC"}
|
|
@@ -7,6 +7,14 @@ const CARD_EXPIRY_FIELD_RE = /\b(exp(?:iry|iration)(?: date)?|cc-exp|valid\s+thr
|
|
|
7
7
|
const CARD_CVC_FIELD_RE = /\b(cvc|cvv|cc-csc|security code|card cvc)\b/i;
|
|
8
8
|
const DATE_VALUE_MASK_RE = /(?:^|\b)(?:dd|d|дд|д)\s*[./-]\s*(?:mm|m|мм|м)\s*[./-]\s*(?:yyyy|yyy|yy|y|гггг|гг|г)(?:\b|$)/i;
|
|
9
9
|
const NON_CARD_DATE_FIELD_RE = /\b(?:birth|dob|date|issued|expires|expiry|expiration|expir)\b|(?:дата|рожд|срок)/i;
|
|
10
|
+
const POPUP_DISCLOSURE_SURFACE_KINDS = new Set([
|
|
11
|
+
'dialog',
|
|
12
|
+
'dropdown',
|
|
13
|
+
'listbox',
|
|
14
|
+
'menu',
|
|
15
|
+
'popover',
|
|
16
|
+
'datepicker',
|
|
17
|
+
]);
|
|
10
18
|
function normalizeText(value) {
|
|
11
19
|
return (value ?? '').trim().toLowerCase();
|
|
12
20
|
}
|
|
@@ -83,6 +91,78 @@ function isButtonLikeInputFacts(facts) {
|
|
|
83
91
|
return (normalizeText(facts.kind) === 'input' &&
|
|
84
92
|
['button', 'submit', 'reset'].includes(normalizeText(facts.inputType)));
|
|
85
93
|
}
|
|
94
|
+
function isSelectionItemLikeFacts(facts) {
|
|
95
|
+
const kind = normalizeText(facts.kind);
|
|
96
|
+
const role = normalizeText(facts.role);
|
|
97
|
+
return (kind === 'option' ||
|
|
98
|
+
role === 'option' ||
|
|
99
|
+
role === 'menuitem' ||
|
|
100
|
+
facts.structure?.family === 'structured-grid');
|
|
101
|
+
}
|
|
102
|
+
function isBinaryToggleControlFacts(facts) {
|
|
103
|
+
const kind = normalizeText(facts.kind);
|
|
104
|
+
const role = normalizeText(facts.role);
|
|
105
|
+
const inputType = normalizeText(facts.inputType);
|
|
106
|
+
return (kind === 'checkbox' ||
|
|
107
|
+
kind === 'radio' ||
|
|
108
|
+
role === 'checkbox' ||
|
|
109
|
+
role === 'radio' ||
|
|
110
|
+
role === 'switch' ||
|
|
111
|
+
kind === 'tab' ||
|
|
112
|
+
role === 'tab' ||
|
|
113
|
+
inputType === 'checkbox' ||
|
|
114
|
+
inputType === 'radio');
|
|
115
|
+
}
|
|
116
|
+
function isDisclosureLikeTriggerFacts(facts, controlFamily) {
|
|
117
|
+
const kind = normalizeText(facts.kind);
|
|
118
|
+
const role = normalizeText(facts.role);
|
|
119
|
+
const surfaceKind = normalizeText(facts.surfaceKind);
|
|
120
|
+
const inputType = normalizeText(facts.inputType);
|
|
121
|
+
const popupBacked = Boolean(facts.controlsSurfaceSelector) ||
|
|
122
|
+
facts.states?.expanded !== undefined ||
|
|
123
|
+
POPUP_DISCLOSURE_SURFACE_KINDS.has(surfaceKind);
|
|
124
|
+
if (!popupBacked) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (isSelectionItemLikeFacts(facts) || controlFamily === 'text-input') {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
if (controlFamily === 'select' || controlFamily === 'datepicker') {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
return (kind === 'button' ||
|
|
134
|
+
role === 'button' ||
|
|
135
|
+
kind === 'link' ||
|
|
136
|
+
role === 'link' ||
|
|
137
|
+
kind === 'combobox' ||
|
|
138
|
+
role === 'combobox' ||
|
|
139
|
+
kind === 'select' ||
|
|
140
|
+
isButtonLikeInputFacts(facts) ||
|
|
141
|
+
inputType === 'button' ||
|
|
142
|
+
isPopupBackedTextEntry(facts));
|
|
143
|
+
}
|
|
144
|
+
function isToggleLikeControlFacts(facts, controlFamily) {
|
|
145
|
+
const states = facts.states;
|
|
146
|
+
if (!states) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
if (states.checked !== undefined || isBinaryToggleControlFacts(facts)) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
if (states.selected !== undefined) {
|
|
153
|
+
if (isSelectionItemLikeFacts(facts) ||
|
|
154
|
+
controlFamily === 'select' ||
|
|
155
|
+
controlFamily === 'datepicker' ||
|
|
156
|
+
isDisclosureLikeTriggerFacts(facts, controlFamily)) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
if (states.pressed !== undefined) {
|
|
162
|
+
return !isDisclosureLikeTriggerFacts(facts, controlFamily);
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
86
166
|
export function isLikelyDateLikeLabel(value) {
|
|
87
167
|
const trimmed = (value ?? '').trim();
|
|
88
168
|
if (!trimmed) {
|
|
@@ -280,17 +360,15 @@ export function inferAcceptancePolicyFromFacts(facts, allowedActions) {
|
|
|
280
360
|
if (facts.structure?.family === 'structured-grid') {
|
|
281
361
|
return facts.structure.variant === 'date-cell' ? 'date-selection' : 'selection';
|
|
282
362
|
}
|
|
283
|
-
if (states?.checked !== undefined ||
|
|
284
|
-
states?.selected !== undefined ||
|
|
285
|
-
states?.pressed !== undefined) {
|
|
286
|
-
return 'toggle';
|
|
287
|
-
}
|
|
288
363
|
if (controlFamily === 'text-input') {
|
|
289
364
|
return 'value-change';
|
|
290
365
|
}
|
|
291
|
-
if (
|
|
366
|
+
if (isDisclosureLikeTriggerFacts(facts, controlFamily)) {
|
|
292
367
|
return 'disclosure';
|
|
293
368
|
}
|
|
369
|
+
if (isToggleLikeControlFacts(facts, controlFamily)) {
|
|
370
|
+
return 'toggle';
|
|
371
|
+
}
|
|
294
372
|
if (controlFamily === 'datepicker') {
|
|
295
373
|
return 'date-selection';
|
|
296
374
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA4QA,iBAAe,IAAI,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4KhE;AAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAEhB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAWzF"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
loadEnv();
|
|
6
6
|
import { preflightAgentpayGateway } from './agentpay-gateway.js';
|
|
7
7
|
import { browseCommand, browseCommandName } from './command-name.js';
|
|
8
|
+
import { assertSemanticObserveRuntimeSupport } from './commands/semantic-observe-lexical.js';
|
|
8
9
|
import { loadSession } from './session.js';
|
|
9
10
|
import { outputError, outputJSON, fatal, info } from './output.js';
|
|
10
11
|
import { applyDemoProxyBootstrap } from './solver/config.js';
|
|
@@ -223,6 +224,12 @@ async function main(argv = process.argv) {
|
|
|
223
224
|
if (!KNOWN_COMMANDS.has(command)) {
|
|
224
225
|
outputError(`Unknown command: ${command}\n\n${usageText()}`);
|
|
225
226
|
}
|
|
227
|
+
try {
|
|
228
|
+
assertSemanticObserveRuntimeSupport();
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
outputError(err instanceof Error ? err.message : String(err));
|
|
232
|
+
}
|
|
226
233
|
if (command !== 'init') {
|
|
227
234
|
try {
|
|
228
235
|
await preflightAgentpayGateway();
|
package/dist/solver/config.js
CHANGED
|
@@ -3,7 +3,7 @@ import os from 'node:os';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
const AGENTPAY_DIR = path.join(os.homedir(), '.agentpay');
|
|
5
5
|
const PRIMARY_DIR = path.join(AGENTPAY_DIR, 'agentbrowse');
|
|
6
|
-
const PRIMARY_CONFIG_PATH = path.join(
|
|
6
|
+
const PRIMARY_CONFIG_PATH = path.join(AGENTPAY_DIR, 'config.json');
|
|
7
7
|
const PRIMARY_PROFILES_DIR = path.join(PRIMARY_DIR, 'profiles');
|
|
8
8
|
const DEMO_PROXY_PLACEHOLDER = 'http://user:pass@31.98.19.10:6186/';
|
|
9
9
|
export function getSolverDir() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuanu-ai/agentbrowse",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.37",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Browser automation CLI for AI agents: control a CDP browser, observe UI surfaces, act on refs, extract data, capture screenshots, complete protected fills, and solve captchas",
|
|
6
6
|
"keywords": [
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"puppeteer": "^23.11.1",
|
|
58
58
|
"puppeteer-extra": "^3.3.6",
|
|
59
59
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
|
60
|
+
"snowball-stemmers": "^0.6.0",
|
|
60
61
|
"zod": "^3.24.0"
|
|
61
62
|
},
|
|
62
63
|
"devDependencies": {
|