@nuanu-ai/agentbrowse 0.2.40 → 0.2.42
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/commands/click-action-executor.d.ts +1 -0
- package/dist/commands/click-action-executor.d.ts.map +1 -1
- package/dist/commands/click-action-executor.js +78 -19
- package/dist/commands/observe-semantics.d.ts +1 -0
- package/dist/commands/observe-semantics.d.ts.map +1 -1
- package/dist/commands/observe-semantics.js +110 -0
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +2 -2
- package/dist/solver/browser-launcher.d.ts.map +1 -1
- package/dist/solver/browser-launcher.js +2 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ type ClickRetryOptions = {
|
|
|
5
5
|
beforeRetry?: () => Promise<void>;
|
|
6
6
|
guards?: ActionExecutionGuards;
|
|
7
7
|
clickActivationStrategy?: ClickActivationStrategy;
|
|
8
|
+
focusStrategy?: 'iframe-only' | 'active-control';
|
|
8
9
|
};
|
|
9
10
|
export declare function applyEditableClickAction(page: Page, locator: Locator, attempts: string[], options?: ClickRetryOptions): Promise<boolean>;
|
|
10
11
|
export declare function applyTriggerAction(page: Page, locator: Locator, attempts: string[], options?: ClickRetryOptions): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"click-action-executor.d.ts","sourceRoot":"","sources":["../../src/commands/click-action-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAMrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEnG,KAAK,iBAAiB,GAAG;IACvB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"click-action-executor.d.ts","sourceRoot":"","sources":["../../src/commands/click-action-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAMrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAA2B,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEnG,KAAK,iBAAiB,GAAG;IACvB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD,aAAa,CAAC,EAAE,aAAa,GAAG,gBAAgB,CAAC;CAClD,CAAC;AA0LF,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAKlB"}
|
|
@@ -1,21 +1,74 @@
|
|
|
1
1
|
import { LOCATOR_CLICK_TIMEOUT_MS, dismissBlockingOverlay, looksLikeOverlayInterference, } from './action-executor-helpers.js';
|
|
2
2
|
import { runActionExecutionGuard } from './action-execution-guards.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
const DEFAULT_FOCUS_ALIGNMENT_RESULT = {
|
|
4
|
+
focused: false,
|
|
5
|
+
kind: null,
|
|
6
|
+
};
|
|
7
|
+
function normalizeFocusAlignmentResult(result) {
|
|
8
|
+
if (result === true) {
|
|
9
|
+
return {
|
|
10
|
+
focused: true,
|
|
11
|
+
kind: 'iframe',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
if (!result || typeof result !== 'object') {
|
|
15
|
+
return DEFAULT_FOCUS_ALIGNMENT_RESULT;
|
|
16
|
+
}
|
|
17
|
+
const candidate = result;
|
|
18
|
+
const focused = candidate.focused === true;
|
|
19
|
+
if (!focused) {
|
|
20
|
+
return DEFAULT_FOCUS_ALIGNMENT_RESULT;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
focused: true,
|
|
24
|
+
kind: candidate.kind === 'iframe' || candidate.kind === 'control' ? candidate.kind : 'control',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async function alignTargetFocusBeforeClick(locator, attempts, focusStrategy) {
|
|
28
|
+
const focusProbeResult = await (focusStrategy === 'iframe-only'
|
|
29
|
+
? locator.evaluate((element) => {
|
|
30
|
+
if (!(element instanceof HTMLElement)) {
|
|
31
|
+
return { focused: false, kind: null };
|
|
32
|
+
}
|
|
33
|
+
const active = element.ownerDocument.activeElement;
|
|
34
|
+
if (!(active instanceof HTMLElement) || active === element) {
|
|
35
|
+
return { focused: false, kind: null };
|
|
36
|
+
}
|
|
37
|
+
if (active === element.ownerDocument.body ||
|
|
38
|
+
active === element.ownerDocument.documentElement ||
|
|
39
|
+
!(active instanceof HTMLIFrameElement)) {
|
|
40
|
+
return { focused: false, kind: null };
|
|
41
|
+
}
|
|
42
|
+
element.focus();
|
|
43
|
+
return {
|
|
44
|
+
focused: element.ownerDocument.activeElement === element,
|
|
45
|
+
kind: 'iframe',
|
|
46
|
+
};
|
|
47
|
+
})
|
|
48
|
+
: locator.evaluate((element) => {
|
|
49
|
+
if (!(element instanceof HTMLElement)) {
|
|
50
|
+
return { focused: false, kind: null };
|
|
51
|
+
}
|
|
52
|
+
const active = element.ownerDocument.activeElement;
|
|
53
|
+
if (!(active instanceof HTMLElement) || active === element) {
|
|
54
|
+
return { focused: false, kind: null };
|
|
55
|
+
}
|
|
56
|
+
if (active === element.ownerDocument.body ||
|
|
57
|
+
active === element.ownerDocument.documentElement) {
|
|
58
|
+
return { focused: false, kind: null };
|
|
59
|
+
}
|
|
60
|
+
const kind = active instanceof HTMLIFrameElement ? 'iframe' : 'control';
|
|
61
|
+
element.focus();
|
|
62
|
+
return {
|
|
63
|
+
focused: element.ownerDocument.activeElement === element,
|
|
64
|
+
kind,
|
|
65
|
+
};
|
|
66
|
+
})).catch(() => DEFAULT_FOCUS_ALIGNMENT_RESULT);
|
|
67
|
+
const focusResult = normalizeFocusAlignmentResult(focusProbeResult);
|
|
68
|
+
if (focusResult.focused) {
|
|
69
|
+
attempts.push(focusResult.kind === 'iframe'
|
|
70
|
+
? 'locator.focus.handoff-from-iframe'
|
|
71
|
+
: 'locator.focus.before-click');
|
|
19
72
|
}
|
|
20
73
|
}
|
|
21
74
|
async function ensureLocatorRetryReady(locator, error, options) {
|
|
@@ -27,7 +80,7 @@ async function ensureLocatorRetryReady(locator, error, options) {
|
|
|
27
80
|
}
|
|
28
81
|
}
|
|
29
82
|
async function applyClickSequence(page, locator, attempts, options) {
|
|
30
|
-
await
|
|
83
|
+
await alignTargetFocusBeforeClick(locator, attempts, options?.focusStrategy ?? 'iframe-only');
|
|
31
84
|
if (options?.clickActivationStrategy === 'dom') {
|
|
32
85
|
await runActionExecutionGuard(options?.guards, 'click.evaluate.primary');
|
|
33
86
|
attempts.push('locator.evaluate.click.primary');
|
|
@@ -91,8 +144,14 @@ async function applyClickSequence(page, locator, attempts, options) {
|
|
|
91
144
|
}
|
|
92
145
|
}
|
|
93
146
|
export async function applyEditableClickAction(page, locator, attempts, options) {
|
|
94
|
-
return applyClickSequence(page, locator, attempts,
|
|
147
|
+
return applyClickSequence(page, locator, attempts, {
|
|
148
|
+
...options,
|
|
149
|
+
focusStrategy: options?.focusStrategy ?? 'iframe-only',
|
|
150
|
+
});
|
|
95
151
|
}
|
|
96
152
|
export async function applyTriggerAction(page, locator, attempts, options) {
|
|
97
|
-
return applyClickSequence(page, locator, attempts,
|
|
153
|
+
return applyClickSequence(page, locator, attempts, {
|
|
154
|
+
...options,
|
|
155
|
+
focusStrategy: options?.focusStrategy ?? 'active-control',
|
|
156
|
+
});
|
|
98
157
|
}
|
|
@@ -4,6 +4,7 @@ export declare function isPrimaryFormControlTarget(target: DomObservedTarget): b
|
|
|
4
4
|
export declare function formGroupingKeyOf(target: DomObservedTarget): string | undefined;
|
|
5
5
|
export declare function observedTargetKey(target: DomObservedTarget): string;
|
|
6
6
|
export declare function expandRerankedFormTargets(targets: ReadonlyArray<DomObservedTarget>, selectedTargets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
7
|
+
export declare function expandCompanionSubmitTargets(targets: ReadonlyArray<DomObservedTarget>, selectedTargets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
7
8
|
export declare function prioritizeGoalActionTargets(instruction: string, selectedTargets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
8
9
|
export declare function compressSemanticallyDuplicateTargets(targets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
9
10
|
export declare function annotateDomTargets(targets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe-semantics.d.ts","sourceRoot":"","sources":["../../src/commands/observe-semantics.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAYjF;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CA6B7E;AAgBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAQ/E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAMnE;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CAyCrB;AAkFD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CA+BrB;AAqBD,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAuBrB;AAkGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,EAAE,CAoFjG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAsFrB"}
|
|
1
|
+
{"version":3,"file":"observe-semantics.d.ts","sourceRoot":"","sources":["../../src/commands/observe-semantics.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAYjF;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CA6B7E;AAgBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAQ/E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAMnE;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CAyCrB;AAsDD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CAsFrB;AAkFD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CA+BrB;AAqBD,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAuBrB;AAkGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,iBAAiB,EAAE,CAoFjG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAsFrB"}
|
|
@@ -94,6 +94,116 @@ export function expandRerankedFormTargets(targets, selectedTargets) {
|
|
|
94
94
|
return (left.label ?? '').localeCompare(right.label ?? '');
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
+
function isSubmitLikeTarget(target) {
|
|
98
|
+
const acceptancePolicy = (target.acceptancePolicy ?? '').trim().toLowerCase();
|
|
99
|
+
const inputType = (target.inputType ?? '').trim().toLowerCase();
|
|
100
|
+
return acceptancePolicy === 'submit' || inputType === 'submit';
|
|
101
|
+
}
|
|
102
|
+
function selectedFormClusterKeyOf(target) {
|
|
103
|
+
const formKey = formGroupingKeyOf(target);
|
|
104
|
+
if (formKey) {
|
|
105
|
+
return `form:${formKey}`;
|
|
106
|
+
}
|
|
107
|
+
const surfaceRef = target.surfaceRef?.trim();
|
|
108
|
+
return surfaceRef ? `surface:${surfaceRef}` : undefined;
|
|
109
|
+
}
|
|
110
|
+
function matchesSelectedFormCluster(target, clusterKey) {
|
|
111
|
+
if (!clusterKey) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (clusterKey.startsWith('form:')) {
|
|
115
|
+
return `form:${formGroupingKeyOf(target)}` === clusterKey;
|
|
116
|
+
}
|
|
117
|
+
if (!clusterKey.startsWith('surface:')) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return `surface:${target.surfaceRef?.trim() ?? ''}` === clusterKey;
|
|
121
|
+
}
|
|
122
|
+
function isStandaloneBottomSubmitInputTarget(target) {
|
|
123
|
+
const inputType = (target.inputType ?? '').trim().toLowerCase();
|
|
124
|
+
if (inputType !== 'submit') {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (target.framePath?.length) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
if (target.surfaceRef?.trim() || formGroupingKeyOf(target)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
return target.context?.layout?.band === 'bottom';
|
|
134
|
+
}
|
|
135
|
+
export function expandCompanionSubmitTargets(targets, selectedTargets) {
|
|
136
|
+
if (selectedTargets.some(isSubmitLikeTarget)) {
|
|
137
|
+
return [...selectedTargets];
|
|
138
|
+
}
|
|
139
|
+
const primarySelectedTargets = selectedTargets.filter(isPrimaryFormControlTarget);
|
|
140
|
+
if (primarySelectedTargets.length < 2) {
|
|
141
|
+
return [...selectedTargets];
|
|
142
|
+
}
|
|
143
|
+
const clusterEntries = new Map();
|
|
144
|
+
for (const target of primarySelectedTargets) {
|
|
145
|
+
const clusterKey = selectedFormClusterKeyOf(target);
|
|
146
|
+
if (!clusterKey) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const existing = clusterEntries.get(clusterKey) ?? {
|
|
150
|
+
count: 0,
|
|
151
|
+
priority: clusterKey.startsWith('form:') ? 2 : 1,
|
|
152
|
+
inFrame: false,
|
|
153
|
+
};
|
|
154
|
+
existing.count += 1;
|
|
155
|
+
existing.inFrame ||= Boolean(target.framePath?.length);
|
|
156
|
+
clusterEntries.set(clusterKey, existing);
|
|
157
|
+
}
|
|
158
|
+
const dominantCluster = [...clusterEntries.entries()]
|
|
159
|
+
.filter(([, entry]) => entry.count >= 2)
|
|
160
|
+
.sort((left, right) => {
|
|
161
|
+
const [, leftEntry] = left;
|
|
162
|
+
const [, rightEntry] = right;
|
|
163
|
+
if (leftEntry.count !== rightEntry.count) {
|
|
164
|
+
return rightEntry.count - leftEntry.count;
|
|
165
|
+
}
|
|
166
|
+
if (leftEntry.priority !== rightEntry.priority) {
|
|
167
|
+
return rightEntry.priority - leftEntry.priority;
|
|
168
|
+
}
|
|
169
|
+
return left[0].localeCompare(right[0]);
|
|
170
|
+
})[0];
|
|
171
|
+
if (!dominantCluster) {
|
|
172
|
+
return [...selectedTargets];
|
|
173
|
+
}
|
|
174
|
+
const [dominantClusterKey, dominantClusterMeta] = dominantCluster;
|
|
175
|
+
const expanded = new Map();
|
|
176
|
+
for (const target of selectedTargets) {
|
|
177
|
+
expanded.set(observedTargetKey(target), target);
|
|
178
|
+
}
|
|
179
|
+
const explicitCompanions = targets.filter((target) => {
|
|
180
|
+
const key = observedTargetKey(target);
|
|
181
|
+
if (expanded.has(key) || !isSubmitLikeTarget(target)) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
return matchesSelectedFormCluster(target, dominantClusterKey);
|
|
185
|
+
});
|
|
186
|
+
for (const target of explicitCompanions) {
|
|
187
|
+
expanded.set(observedTargetKey(target), target);
|
|
188
|
+
}
|
|
189
|
+
if (explicitCompanions.length === 0 && dominantClusterMeta.inFrame) {
|
|
190
|
+
const fallbackCandidates = targets.filter((target) => {
|
|
191
|
+
const key = observedTargetKey(target);
|
|
192
|
+
return !expanded.has(key) && isStandaloneBottomSubmitInputTarget(target);
|
|
193
|
+
});
|
|
194
|
+
if (fallbackCandidates.length === 1) {
|
|
195
|
+
expanded.set(observedTargetKey(fallbackCandidates[0]), fallbackCandidates[0]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return [...expanded.values()].sort((left, right) => {
|
|
199
|
+
const leftOrdinal = left.ordinal ?? Number.MAX_SAFE_INTEGER;
|
|
200
|
+
const rightOrdinal = right.ordinal ?? Number.MAX_SAFE_INTEGER;
|
|
201
|
+
if (leftOrdinal !== rightOrdinal) {
|
|
202
|
+
return leftOrdinal - rightOrdinal;
|
|
203
|
+
}
|
|
204
|
+
return (left.label ?? '').localeCompare(right.label ?? '');
|
|
205
|
+
});
|
|
206
|
+
}
|
|
97
207
|
function parseNumericAmount(value) {
|
|
98
208
|
const normalized = value.replace(/,/g, '.').trim();
|
|
99
209
|
if (!/^\d+(?:\.\d+)?$/.test(normalized)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/commands/observe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/commands/observe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA4DnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,eAAO,MAAM,yBAAyB;;;;iBA4Uk6G,CAAC;gBAAwB,CAAC;;;;;CA5U75G,CAAC;AACtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGrC,CAAC;AAEF,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqUzF"}
|
package/dist/commands/observe.js
CHANGED
|
@@ -14,7 +14,7 @@ import { collectPageSignals } from './observe-signals.js';
|
|
|
14
14
|
import { attachObservedTargetOwners, linkObservedSurfaceGraph, reconcileObservedTargetsForPage, persistObservedSurfacesForPage, toDomDescriptor, } from './observe-persistence.js';
|
|
15
15
|
import { clearProtectedFillableFormsForPage, persistProtectedFillableFormsForPage, } from './observe-protected.js';
|
|
16
16
|
import { classifyObservePageState, shouldSuppressFillableFormsForObserve, } from './observe-page-state.js';
|
|
17
|
-
import { annotateDomTargets, compressSemanticallyDuplicateTargets, expandRerankedFormTargets, orderBySurfaceCompetition, prioritizeGoalActionTargets, } from './observe-semantics.js';
|
|
17
|
+
import { annotateDomTargets, compressSemanticallyDuplicateTargets, expandCompanionSubmitTargets, expandRerankedFormTargets, orderBySurfaceCompetition, prioritizeGoalActionTargets, } from './observe-semantics.js';
|
|
18
18
|
import { buildGroupedObserveScopes, buildExplicitScopeRefs, buildGoalObserveInventoryCandidates, compactFillableForms, compactSignals, projectPersistedTargetsForGoal, selectTargetsForGoalMatches, } from './observe-projection.js';
|
|
19
19
|
import { collectSurfaceDescriptors, selectScopesForOutput } from './observe-surfaces.js';
|
|
20
20
|
import { toStagehandDescriptor } from './observe-stagehand.js';
|
|
@@ -126,7 +126,7 @@ export async function observe(session, instruction) {
|
|
|
126
126
|
if (domTargets.length > 0) {
|
|
127
127
|
const rerankedCandidates = await rerankDomTargetsForGoal(instruction, buildGoalObserveInventoryCandidates(domTargets, surfaceInputs), { session });
|
|
128
128
|
const { targets: goalMatchedTargets, selectedSurfaceIds } = selectTargetsForGoalMatches(domTargets, rerankedCandidates);
|
|
129
|
-
const selectedTargets = prioritizeGoalActionTargets(instruction, expandRerankedFormTargets(domTargets, goalMatchedTargets));
|
|
129
|
+
const selectedTargets = prioritizeGoalActionTargets(instruction, expandCompanionSubmitTargets(domTargets, expandRerankedFormTargets(domTargets, goalMatchedTargets)));
|
|
130
130
|
const persisted = persistObservedSurfacesForPage(session, pageRef, domTargets, {
|
|
131
131
|
allSurfaceInputs: surfaceInputs,
|
|
132
132
|
explicitSurfaceIds: selectedSurfaceIds,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-launcher.d.ts","sourceRoot":"","sources":["../../src/solver/browser-launcher.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAsB,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-launcher.d.ts","sourceRoot":"","sources":["../../src/solver/browser-launcher.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAsB,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkBjF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAuBF,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,aAAa,CAAC,CAmExB;AAkUD,wBAAgB,wBAAwB,CACtC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAGV"}
|
|
@@ -9,6 +9,8 @@ const enhancedPuppeteer = puppeteerExtra;
|
|
|
9
9
|
const solverStealthPlugin = StealthPlugin();
|
|
10
10
|
// Some iframe-backed checkout flows break when this evasion runs on a connected real Chrome.
|
|
11
11
|
solverStealthPlugin.enabledEvasions.delete('iframe.contentWindow');
|
|
12
|
+
// We already pin the browser UA at launch time; this evasion races popup teardown on CI.
|
|
13
|
+
solverStealthPlugin.enabledEvasions.delete('user-agent-override');
|
|
12
14
|
enhancedPuppeteer.use(solverStealthPlugin);
|
|
13
15
|
const AUTO_CDP_PORT = 0;
|
|
14
16
|
const CDP_DISCOVERY_TIMEOUT_MS = 30_000;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuanu-ai/agentbrowse",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.42",
|
|
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": [
|