@nuanu-ai/agentbrowse 0.2.9 → 0.2.11
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/README.md +3 -2
- package/dist/commands/click-action-executor.d.ts.map +1 -1
- package/dist/commands/click-action-executor.js +20 -1
- package/dist/commands/observe-projection.d.ts.map +1 -1
- package/dist/commands/observe-projection.js +60 -20
- 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 +87 -0
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,8 +118,9 @@ Default verification for this package is no longer unit-only:
|
|
|
118
118
|
- `pnpm --filter @nuanu-ai/agentbrowse test` includes local fixture browser integration coverage for runtime and extract flows
|
|
119
119
|
- the default suite also covers one explicit Stagehand-assisted observe fallback plus launch/session smoke at the command boundary
|
|
120
120
|
|
|
121
|
-
See
|
|
121
|
+
See package docs:
|
|
122
122
|
|
|
123
|
-
- [
|
|
123
|
+
- [packages/browse-cli/docs/README.md](/Users/dmitry/Dev/mercuryo-agent-pay/packages/browse-cli/docs/README.md)
|
|
124
|
+
- [packages/browse-cli/docs/testing/cli-usage-guide.md](/Users/dmitry/Dev/mercuryo-agent-pay/packages/browse-cli/docs/testing/cli-usage-guide.md)
|
|
124
125
|
|
|
125
126
|
Releases are published automatically from `main` after checks pass. `@nuanu-ai/agentbrowse` is the only CLI package published by the current npm release workflow.
|
|
@@ -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,
|
|
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,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;CAChC,CAAC;AA+FF,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,CAElB;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,CAElB"}
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { LOCATOR_CLICK_TIMEOUT_MS, dismissBlockingOverlay, looksLikeOverlayInterference, } from './action-executor-helpers.js';
|
|
2
|
-
import { runActionExecutionGuard
|
|
2
|
+
import { runActionExecutionGuard } from './action-execution-guards.js';
|
|
3
|
+
async function handoffFocusFromActiveIframe(locator, attempts) {
|
|
4
|
+
const focused = await locator
|
|
5
|
+
.evaluate((element) => {
|
|
6
|
+
if (!(element instanceof HTMLElement)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const active = element.ownerDocument.activeElement;
|
|
10
|
+
if (!(active instanceof HTMLIFrameElement)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
element.focus();
|
|
14
|
+
return element.ownerDocument.activeElement === element;
|
|
15
|
+
})
|
|
16
|
+
.catch(() => false);
|
|
17
|
+
if (focused) {
|
|
18
|
+
attempts.push('locator.focus.handoff-from-iframe');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
3
21
|
async function ensureLocatorRetryReady(locator, error, options) {
|
|
4
22
|
await runActionExecutionGuard(options?.guards, 'click.before-retry');
|
|
5
23
|
await options?.beforeRetry?.();
|
|
@@ -9,6 +27,7 @@ async function ensureLocatorRetryReady(locator, error, options) {
|
|
|
9
27
|
}
|
|
10
28
|
}
|
|
11
29
|
async function applyClickSequence(page, locator, attempts, options) {
|
|
30
|
+
await handoffFocusFromActiveIframe(locator, attempts);
|
|
12
31
|
attempts.push('locator.click');
|
|
13
32
|
try {
|
|
14
33
|
await locator.click({ timeout: LOCATOR_CLICK_TIMEOUT_MS });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe-projection.d.ts","sourceRoot":"","sources":["../../src/commands/observe-projection.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"observe-projection.d.ts","sourceRoot":"","sources":["../../src/commands/observe-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -97,25 +97,51 @@ function isGoalObserveScopeCandidate(candidate) {
|
|
|
97
97
|
return candidate.goalInventoryType === 'scope';
|
|
98
98
|
}
|
|
99
99
|
export function selectTargetsForGoalMatches(allTargets, rerankedCandidates) {
|
|
100
|
-
const directTargetOrdinals = new Set(
|
|
101
|
-
|
|
102
|
-
.map((candidate) => candidate.ordinal)
|
|
103
|
-
.filter((value) => typeof value === 'number'));
|
|
104
|
-
const directTargetKeys = new Set(rerankedCandidates
|
|
105
|
-
.filter(isGoalObserveTargetCandidate)
|
|
106
|
-
.map((candidate) => candidate.goalTargetKey)
|
|
107
|
-
.filter((value) => typeof value === 'string' && value.length > 0));
|
|
100
|
+
const directTargetOrdinals = new Set();
|
|
101
|
+
const directTargetKeys = new Set();
|
|
108
102
|
const selectedSurfaceIds = new Set(rerankedCandidates
|
|
109
103
|
.filter(isGoalObserveScopeCandidate)
|
|
110
104
|
.map((candidate) => candidate.goalSurfaceId));
|
|
111
|
-
const
|
|
105
|
+
const matchedTargets = [];
|
|
106
|
+
const seenTargetKeys = new Set();
|
|
107
|
+
for (const candidate of rerankedCandidates) {
|
|
108
|
+
if (!isGoalObserveTargetCandidate(candidate)) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (typeof candidate.ordinal === 'number') {
|
|
112
|
+
directTargetOrdinals.add(candidate.ordinal);
|
|
113
|
+
}
|
|
114
|
+
if (typeof candidate.goalTargetKey === 'string' && candidate.goalTargetKey.length > 0) {
|
|
115
|
+
directTargetKeys.add(candidate.goalTargetKey);
|
|
116
|
+
}
|
|
117
|
+
const matchedTarget = allTargets.find((target) => {
|
|
118
|
+
const directMatch = typeof candidate.ordinal === 'number' &&
|
|
119
|
+
typeof target.ordinal === 'number' &&
|
|
120
|
+
target.ordinal === candidate.ordinal;
|
|
121
|
+
const directKeyMatch = observedTargetKey(target) === candidate.goalTargetKey;
|
|
122
|
+
return directMatch || directKeyMatch;
|
|
123
|
+
});
|
|
124
|
+
if (!matchedTarget) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const observedKey = observedTargetKey(matchedTarget);
|
|
128
|
+
if (seenTargetKeys.has(observedKey)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
seenTargetKeys.add(observedKey);
|
|
132
|
+
matchedTargets.push(matchedTarget);
|
|
133
|
+
}
|
|
134
|
+
const scopeTargets = allTargets.filter((target) => {
|
|
112
135
|
const directMatch = typeof target.ordinal === 'number' && directTargetOrdinals.has(target.ordinal);
|
|
113
136
|
const directKeyMatch = directTargetKeys.has(observedTargetKey(target));
|
|
114
137
|
const scopeMatch = target.surfaceRef ? selectedSurfaceIds.has(target.surfaceRef) : false;
|
|
115
|
-
|
|
138
|
+
if (directMatch || directKeyMatch) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
return scopeMatch;
|
|
116
142
|
});
|
|
117
143
|
return {
|
|
118
|
-
targets:
|
|
144
|
+
targets: [...matchedTargets, ...scopeTargets],
|
|
119
145
|
selectedSurfaceIds,
|
|
120
146
|
};
|
|
121
147
|
}
|
|
@@ -125,17 +151,31 @@ export function buildExplicitScopeRefs(selectedSurfaceIds, surfaceRefMap) {
|
|
|
125
151
|
.filter((value) => typeof value === 'string' && value.length > 0));
|
|
126
152
|
}
|
|
127
153
|
export function projectPersistedTargetsForGoal(domTargets, persistedTargets, selectedTargets) {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const selectedKeys = new Set(selectedTargets.map((target) => observedTargetKey(target)));
|
|
132
|
-
return persistedTargets.filter((target, index) => {
|
|
154
|
+
const persistedByKey = new Map();
|
|
155
|
+
const persistedByOrdinal = new Map();
|
|
156
|
+
persistedTargets.forEach((target, index) => {
|
|
133
157
|
const domTarget = domTargets[index];
|
|
134
158
|
if (!domTarget) {
|
|
135
|
-
return
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
persistedByKey.set(observedTargetKey(domTarget), target);
|
|
162
|
+
if (typeof domTarget.ordinal === 'number') {
|
|
163
|
+
persistedByOrdinal.set(domTarget.ordinal, target);
|
|
136
164
|
}
|
|
137
|
-
const ordinalMatch = typeof domTarget.ordinal === 'number' && selectedOrdinals.has(domTarget.ordinal);
|
|
138
|
-
const keyMatch = selectedKeys.has(observedTargetKey(domTarget));
|
|
139
|
-
return ordinalMatch || keyMatch;
|
|
140
165
|
});
|
|
166
|
+
const projected = [];
|
|
167
|
+
const seenRefs = new Set();
|
|
168
|
+
for (const selectedTarget of selectedTargets) {
|
|
169
|
+
const byKey = persistedByKey.get(observedTargetKey(selectedTarget));
|
|
170
|
+
const byOrdinal = typeof selectedTarget.ordinal === 'number'
|
|
171
|
+
? persistedByOrdinal.get(selectedTarget.ordinal)
|
|
172
|
+
: undefined;
|
|
173
|
+
const persistedTarget = byKey ?? byOrdinal;
|
|
174
|
+
if (!persistedTarget || seenRefs.has(persistedTarget.ref)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
seenRefs.add(persistedTarget.ref);
|
|
178
|
+
projected.push(persistedTarget);
|
|
179
|
+
}
|
|
180
|
+
return projected;
|
|
141
181
|
}
|
|
@@ -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 prioritizeGoalActionTargets(instruction: string, selectedTargets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
7
8
|
export declare function compressSemanticallyDuplicateTargets(targets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
8
9
|
export declare function annotateDomTargets(targets: ReadonlyArray<DomObservedTarget>): DomObservedTarget[];
|
|
9
10
|
export declare function orderBySurfaceCompetition(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;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,CAmDjG;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;AAkFD,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAChD,iBAAiB,EAAE,CA6BrB;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,CAmDjG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACxC,iBAAiB,EAAE,CAsFrB"}
|
|
@@ -94,6 +94,93 @@ export function expandRerankedFormTargets(targets, selectedTargets) {
|
|
|
94
94
|
return (left.label ?? '').localeCompare(right.label ?? '');
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
+
function parseNumericAmount(value) {
|
|
98
|
+
const normalized = value.replace(/,/g, '.').trim();
|
|
99
|
+
if (!/^\d+(?:\.\d+)?$/.test(normalized)) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const parsed = Number(normalized);
|
|
103
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
104
|
+
}
|
|
105
|
+
function parseGoalAmount(instruction) {
|
|
106
|
+
const normalized = instruction.trim().toLowerCase();
|
|
107
|
+
if (!normalized) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const currencyPattern = /\b(\d+(?:[.,]\d+)?)\s*(?:usd|us dollars?|united states dollars?|dollars?)\b|\$(\d+(?:[.,]\d+)?)/i;
|
|
111
|
+
const match = normalized.match(currencyPattern);
|
|
112
|
+
if (!match) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return parseNumericAmount(match[1] ?? match[2] ?? '');
|
|
116
|
+
}
|
|
117
|
+
function goalLooksLikePurchaseStart(instruction) {
|
|
118
|
+
return /\b(start|buy|support|purchase|pay|checkout|donat(?:e|ion))\b/i.test(instruction);
|
|
119
|
+
}
|
|
120
|
+
function targetLabelAmount(target) {
|
|
121
|
+
const candidates = [
|
|
122
|
+
target.label,
|
|
123
|
+
target.displayLabel,
|
|
124
|
+
target.text,
|
|
125
|
+
target.placeholder,
|
|
126
|
+
target.title,
|
|
127
|
+
].filter((value) => typeof value === 'string' && value.trim().length > 0);
|
|
128
|
+
for (const candidate of candidates) {
|
|
129
|
+
const currencyMatch = candidate.match(/\b(\d+(?:[.,]\d+)?)\s*(?:usd|us dollars?|united states dollars?|dollars?)\b|\$(\d+(?:[.,]\d+)?)/i);
|
|
130
|
+
if (currencyMatch) {
|
|
131
|
+
return parseNumericAmount(currencyMatch[1] ?? currencyMatch[2] ?? '');
|
|
132
|
+
}
|
|
133
|
+
const exactNumeric = parseNumericAmount(candidate);
|
|
134
|
+
if (exactNumeric !== null) {
|
|
135
|
+
return exactNumeric;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
function isExactAmountSubmitTarget(target, amount) {
|
|
141
|
+
const acceptancePolicy = (target.acceptancePolicy ?? '').trim().toLowerCase();
|
|
142
|
+
const labelAmount = targetLabelAmount(target);
|
|
143
|
+
if (labelAmount !== amount) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if (acceptancePolicy === 'submit') {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
const label = `${target.label ?? ''} ${target.displayLabel ?? ''}`.toLowerCase();
|
|
150
|
+
return /\b(support|pay|buy|checkout|donate)\b/.test(label);
|
|
151
|
+
}
|
|
152
|
+
function isExactAmountSelectionTarget(target, amount) {
|
|
153
|
+
const acceptancePolicy = (target.acceptancePolicy ?? '').trim().toLowerCase();
|
|
154
|
+
const inputType = (target.inputType ?? '').trim().toLowerCase();
|
|
155
|
+
return (targetLabelAmount(target) === amount &&
|
|
156
|
+
(acceptancePolicy === 'selection' || inputType === 'radio'));
|
|
157
|
+
}
|
|
158
|
+
export function prioritizeGoalActionTargets(instruction, selectedTargets) {
|
|
159
|
+
const goalAmount = parseGoalAmount(instruction);
|
|
160
|
+
if (goalAmount === null || !goalLooksLikePurchaseStart(instruction)) {
|
|
161
|
+
return [...selectedTargets];
|
|
162
|
+
}
|
|
163
|
+
const hasExactSubmit = selectedTargets.some((target) => isExactAmountSubmitTarget(target, goalAmount));
|
|
164
|
+
if (!hasExactSubmit) {
|
|
165
|
+
return [...selectedTargets];
|
|
166
|
+
}
|
|
167
|
+
return [...selectedTargets]
|
|
168
|
+
.map((target, index) => ({ target, index }))
|
|
169
|
+
.sort((left, right) => {
|
|
170
|
+
const leftIsSubmit = isExactAmountSubmitTarget(left.target, goalAmount);
|
|
171
|
+
const rightIsSubmit = isExactAmountSubmitTarget(right.target, goalAmount);
|
|
172
|
+
if (leftIsSubmit !== rightIsSubmit) {
|
|
173
|
+
return leftIsSubmit ? -1 : 1;
|
|
174
|
+
}
|
|
175
|
+
const leftIsSelection = isExactAmountSelectionTarget(left.target, goalAmount);
|
|
176
|
+
const rightIsSelection = isExactAmountSelectionTarget(right.target, goalAmount);
|
|
177
|
+
if (leftIsSelection !== rightIsSelection) {
|
|
178
|
+
return leftIsSelection ? 1 : -1;
|
|
179
|
+
}
|
|
180
|
+
return left.index - right.index;
|
|
181
|
+
})
|
|
182
|
+
.map(({ target }) => target);
|
|
183
|
+
}
|
|
97
184
|
function semanticCompressionKey(target) {
|
|
98
185
|
const band = target.context?.layout?.band;
|
|
99
186
|
if (band !== 'bottom') {
|
|
@@ -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;AAgDnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,eAAO,MAAM,yBAAyB;;;;iBA6OguF,CAAC;gBAAwB,CAAC;;;;;iBAAq7vE,CAAC;gBAAwB,CAAC;;;CA7O1q1E,CAAC;AACtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGrC,CAAC;AAEF,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsOzF"}
|
package/dist/commands/observe.js
CHANGED
|
@@ -11,7 +11,7 @@ import { normalizePageSignature } from './descriptor-validation.js';
|
|
|
11
11
|
import { collectDomTargets, collectPageSignals, __testDomTargetCollection as inventoryDomTargetCollection, __testStagehandDescriptor as inventoryStagehandDescriptor, } from './observe-inventory.js';
|
|
12
12
|
import { attachObservedTargetOwners, reconcileObservedTargetsForPage, persistObservedSurfacesForPage, toDomDescriptor, } from './observe-persistence.js';
|
|
13
13
|
import { clearProtectedFillableFormsForPage, persistProtectedFillableFormsForPage, } from './observe-protected.js';
|
|
14
|
-
import { annotateDomTargets, compressSemanticallyDuplicateTargets, expandRerankedFormTargets, orderBySurfaceCompetition, } from './observe-semantics.js';
|
|
14
|
+
import { annotateDomTargets, compressSemanticallyDuplicateTargets, expandRerankedFormTargets, orderBySurfaceCompetition, prioritizeGoalActionTargets, } from './observe-semantics.js';
|
|
15
15
|
import { buildExplicitScopeRefs, buildGoalObserveInventoryCandidates, compactFillableForms, compactScopes, compactSignals, compactTargets, projectPersistedTargetsForGoal, selectTargetsForGoalMatches, } from './observe-projection.js';
|
|
16
16
|
import { collectSurfaceDescriptors, selectScopesForOutput } from './observe-surfaces.js';
|
|
17
17
|
import { toStagehandDescriptor } from './observe-stagehand.js';
|
|
@@ -82,7 +82,7 @@ export async function observe(session, instruction) {
|
|
|
82
82
|
if (domTargets.length > 0) {
|
|
83
83
|
const rerankedCandidates = await rerankDomTargetsForGoal(instruction, buildGoalObserveInventoryCandidates(domTargets, surfaceInputs));
|
|
84
84
|
const { targets: goalMatchedTargets, selectedSurfaceIds } = selectTargetsForGoalMatches(domTargets, rerankedCandidates);
|
|
85
|
-
const selectedTargets = expandRerankedFormTargets(domTargets, goalMatchedTargets);
|
|
85
|
+
const selectedTargets = prioritizeGoalActionTargets(instruction, expandRerankedFormTargets(domTargets, goalMatchedTargets));
|
|
86
86
|
if (selectedTargets.length > 0 || selectedSurfaceIds.size > 0) {
|
|
87
87
|
const persisted = persistObservedSurfacesForPage(session, pageRef, domTargets, {
|
|
88
88
|
allSurfaceInputs: surfaceInputs,
|