@nuanu-ai/agentbrowse 0.2.8 → 0.2.10
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.map +1 -1
- package/dist/commands/click-action-executor.js +20 -1
- package/dist/commands/observe-projection.d.ts +2 -1
- package/dist/commands/observe-projection.d.ts.map +1 -1
- package/dist/commands/observe-projection.js +61 -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/dist/secrets/form-matcher.d.ts.map +1 -1
- package/dist/secrets/form-matcher.js +19 -7
- package/dist/secrets/request-guidance.d.ts +24 -0
- package/dist/secrets/request-guidance.d.ts.map +1 -0
- package/dist/secrets/request-guidance.js +142 -0
- package/dist/secrets/types.d.ts +7 -0
- package/dist/secrets/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
import type { SurfaceDescriptor, TargetDescriptor, TargetValidationEvidence } from '../runtime-state.js';
|
|
2
|
-
import type { PersistedFillableForm, ProtectedBindingValueHint } from '../secrets/types.js';
|
|
2
|
+
import type { FillableFormGuidanceHint, PersistedFillableForm, ProtectedBindingValueHint } from '../secrets/types.js';
|
|
3
3
|
import type { DomObservedTarget, ObservedPageSignal } from './observe-inventory.js';
|
|
4
4
|
export type GoalObserveScopeCandidate = {
|
|
5
5
|
goalInventoryType: 'scope';
|
|
@@ -52,6 +52,7 @@ export declare function compactFillableForms(forms: ReadonlyArray<PersistedFilla
|
|
|
52
52
|
scopeRef?: string;
|
|
53
53
|
purpose: string;
|
|
54
54
|
recommendedTiming?: 'late';
|
|
55
|
+
guidance?: FillableFormGuidanceHint;
|
|
55
56
|
fields: Array<{
|
|
56
57
|
fieldKey: string;
|
|
57
58
|
targetRef: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe-projection.d.ts","sourceRoot":"","sources":["../../src/commands/observe-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"observe-projection.d.ts","sourceRoot":"","sources":["../../src/commands/observe-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,6 +37,7 @@ export function compactFillableForms(forms) {
|
|
|
37
37
|
scopeRef: form.scopeRef,
|
|
38
38
|
purpose: form.purpose,
|
|
39
39
|
recommendedTiming: form.recommendedTiming,
|
|
40
|
+
guidance: form.guidance,
|
|
40
41
|
fields: form.fields.map((field) => ({
|
|
41
42
|
fieldKey: field.fieldKey,
|
|
42
43
|
targetRef: field.targetRef,
|
|
@@ -96,25 +97,51 @@ function isGoalObserveScopeCandidate(candidate) {
|
|
|
96
97
|
return candidate.goalInventoryType === 'scope';
|
|
97
98
|
}
|
|
98
99
|
export function selectTargetsForGoalMatches(allTargets, rerankedCandidates) {
|
|
99
|
-
const directTargetOrdinals = new Set(
|
|
100
|
-
|
|
101
|
-
.map((candidate) => candidate.ordinal)
|
|
102
|
-
.filter((value) => typeof value === 'number'));
|
|
103
|
-
const directTargetKeys = new Set(rerankedCandidates
|
|
104
|
-
.filter(isGoalObserveTargetCandidate)
|
|
105
|
-
.map((candidate) => candidate.goalTargetKey)
|
|
106
|
-
.filter((value) => typeof value === 'string' && value.length > 0));
|
|
100
|
+
const directTargetOrdinals = new Set();
|
|
101
|
+
const directTargetKeys = new Set();
|
|
107
102
|
const selectedSurfaceIds = new Set(rerankedCandidates
|
|
108
103
|
.filter(isGoalObserveScopeCandidate)
|
|
109
104
|
.map((candidate) => candidate.goalSurfaceId));
|
|
110
|
-
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) => {
|
|
111
135
|
const directMatch = typeof target.ordinal === 'number' && directTargetOrdinals.has(target.ordinal);
|
|
112
136
|
const directKeyMatch = directTargetKeys.has(observedTargetKey(target));
|
|
113
137
|
const scopeMatch = target.surfaceRef ? selectedSurfaceIds.has(target.surfaceRef) : false;
|
|
114
|
-
|
|
138
|
+
if (directMatch || directKeyMatch) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
return scopeMatch;
|
|
115
142
|
});
|
|
116
143
|
return {
|
|
117
|
-
targets:
|
|
144
|
+
targets: [...matchedTargets, ...scopeTargets],
|
|
118
145
|
selectedSurfaceIds,
|
|
119
146
|
};
|
|
120
147
|
}
|
|
@@ -124,17 +151,31 @@ export function buildExplicitScopeRefs(selectedSurfaceIds, surfaceRefMap) {
|
|
|
124
151
|
.filter((value) => typeof value === 'string' && value.length > 0));
|
|
125
152
|
}
|
|
126
153
|
export function projectPersistedTargetsForGoal(domTargets, persistedTargets, selectedTargets) {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const selectedKeys = new Set(selectedTargets.map((target) => observedTargetKey(target)));
|
|
131
|
-
return persistedTargets.filter((target, index) => {
|
|
154
|
+
const persistedByKey = new Map();
|
|
155
|
+
const persistedByOrdinal = new Map();
|
|
156
|
+
persistedTargets.forEach((target, index) => {
|
|
132
157
|
const domTarget = domTargets[index];
|
|
133
158
|
if (!domTarget) {
|
|
134
|
-
return
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
persistedByKey.set(observedTargetKey(domTarget), target);
|
|
162
|
+
if (typeof domTarget.ordinal === 'number') {
|
|
163
|
+
persistedByOrdinal.set(domTarget.ordinal, target);
|
|
135
164
|
}
|
|
136
|
-
const ordinalMatch = typeof domTarget.ordinal === 'number' && selectedOrdinals.has(domTarget.ordinal);
|
|
137
|
-
const keyMatch = selectedKeys.has(observedTargetKey(domTarget));
|
|
138
|
-
return ordinalMatch || keyMatch;
|
|
139
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;
|
|
140
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,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-matcher.d.ts","sourceRoot":"","sources":["../../src/secrets/form-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,qBAAqB,CAAC;AACrF,OAAO,KAAK,EACV,wBAAwB,EAExB,qBAAqB,EACrB,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"form-matcher.d.ts","sourceRoot":"","sources":["../../src/secrets/form-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,qBAAqB,CAAC;AACrF,OAAO,KAAK,EACV,wBAAwB,EAExB,qBAAqB,EACrB,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAUpB,KAAK,iBAAiB,GAAG,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;AAEhE,UAAU,cAAc;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC9C;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAsBD,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAW3B,CAAC;AAsCH,iBAAS,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAS3D;AAED,iBAAS,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAsC1D;AA6OD,iBAAS,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAgBxD;AAED,iBAAS,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,eAAe,EAAE,CAkBvF;AAoFD,iBAAS,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CAalF;AAED,iBAAS,gBAAgB,CACvB,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,GACnF,wBAAwB,EAAE,CA6C5B;AA6KD,wBAAsB,mCAAmC,CACvD,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACxC,OAAO,EAAE,qBAAqB,GAAG,IAAI,EACrC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA0D9B;AAED,eAAO,MAAM,iBAAiB;;;;;;;CAO7B,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { AgentpayStagehandLlmClient } from '../agentpay-stagehand-llm.js';
|
|
3
3
|
import { tryResolveAgentpayGatewayConfig } from '../agentpay-gateway.js';
|
|
4
|
-
import { IDENTITY_FIELD_KEYS, LOGIN_FIELD_KEYS, PAYMENT_CARD_FIELD_KEYS
|
|
4
|
+
import { IDENTITY_FIELD_KEYS, LOGIN_FIELD_KEYS, PAYMENT_CARD_FIELD_KEYS } from './types.js';
|
|
5
5
|
import { recommendedTimingForProtectedForm } from './fill-ordering.js';
|
|
6
6
|
import { normalizeProtectedBindingValueHint, protectedBindingKey, protectedBindingValueHintSchema, } from './protected-bindings.js';
|
|
7
|
+
import { buildFillableFormGuidance } from './request-guidance.js';
|
|
7
8
|
const PROMPT_VALUE_MAX_CHARS = 180;
|
|
8
9
|
const PROMPT_SIGNAL_MAX_CHARS = 220;
|
|
9
10
|
const PROMPT_SIGNAL_MAX_VALUES = 8;
|
|
@@ -123,7 +124,9 @@ function localSignalValuesOf(target) {
|
|
|
123
124
|
}
|
|
124
125
|
continue;
|
|
125
126
|
}
|
|
126
|
-
if (candidate.strategy === 'label' ||
|
|
127
|
+
if (candidate.strategy === 'label' ||
|
|
128
|
+
candidate.strategy === 'placeholder' ||
|
|
129
|
+
candidate.strategy === 'title') {
|
|
127
130
|
push(candidate.value);
|
|
128
131
|
}
|
|
129
132
|
}
|
|
@@ -133,7 +136,9 @@ function targetLooksLikePaymentCardCore(target) {
|
|
|
133
136
|
const autocomplete = normalizeText(target.autocomplete);
|
|
134
137
|
const inputName = normalizeText(target.inputName);
|
|
135
138
|
const signals = localSignalValuesOf(target);
|
|
136
|
-
if (autocomplete.includes('cc-number') ||
|
|
139
|
+
if (autocomplete.includes('cc-number') ||
|
|
140
|
+
autocomplete.includes('cc-exp') ||
|
|
141
|
+
autocomplete.includes('cc-csc')) {
|
|
137
142
|
return true;
|
|
138
143
|
}
|
|
139
144
|
if (signals.some((signal) => PAYMENT_CARD_CORE_SIGNAL_RE.test(signal))) {
|
|
@@ -229,6 +234,7 @@ function deterministicPaymentCardPlan(plannerGroup, fullGroup) {
|
|
|
229
234
|
fieldKey,
|
|
230
235
|
targetRef,
|
|
231
236
|
label: targetByRef.get(targetRef)?.displayLabel ?? targetByRef.get(targetRef)?.label,
|
|
237
|
+
required: targetByRef.get(targetRef)?.validation?.required,
|
|
232
238
|
valueHint: 'direct',
|
|
233
239
|
});
|
|
234
240
|
};
|
|
@@ -420,7 +426,9 @@ function sanitizeBindings(kind, group, bindings) {
|
|
|
420
426
|
uniqueBindings.set(key, {
|
|
421
427
|
fieldKey,
|
|
422
428
|
targetRef: binding.targetRef,
|
|
423
|
-
label: targetByRef.get(binding.targetRef)?.displayLabel ??
|
|
429
|
+
label: targetByRef.get(binding.targetRef)?.displayLabel ??
|
|
430
|
+
targetByRef.get(binding.targetRef)?.label,
|
|
431
|
+
required: targetByRef.get(binding.targetRef)?.validation?.required,
|
|
424
432
|
valueHint: normalizedValueHint,
|
|
425
433
|
});
|
|
426
434
|
}
|
|
@@ -548,9 +556,7 @@ export async function matchStoredSecretsToObservedTargets(pageRef, targets, cata
|
|
|
548
556
|
if (!catalog) {
|
|
549
557
|
return [];
|
|
550
558
|
}
|
|
551
|
-
const gateway = options.gatewayConfig === undefined
|
|
552
|
-
? tryResolveAgentpayGatewayConfig()
|
|
553
|
-
: options.gatewayConfig;
|
|
559
|
+
const gateway = options.gatewayConfig === undefined ? tryResolveAgentpayGatewayConfig() : options.gatewayConfig;
|
|
554
560
|
if (!gateway) {
|
|
555
561
|
return [];
|
|
556
562
|
}
|
|
@@ -578,6 +584,12 @@ export async function matchStoredSecretsToObservedTargets(pageRef, targets, cata
|
|
|
578
584
|
scopeRef: formScopeRef(planned.fields, targetByRef),
|
|
579
585
|
purpose: kind,
|
|
580
586
|
recommendedTiming: recommendedTimingForProtectedForm(kind),
|
|
587
|
+
guidance: buildFillableFormGuidance({
|
|
588
|
+
purpose: kind,
|
|
589
|
+
recommendedTiming: recommendedTimingForProtectedForm(kind),
|
|
590
|
+
fields: planned.fields,
|
|
591
|
+
targetByRef,
|
|
592
|
+
}),
|
|
581
593
|
fields: planned.fields,
|
|
582
594
|
storedSecretCandidates,
|
|
583
595
|
observedAt: nextObservedAt,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { TargetDescriptor } from '../runtime-state.js';
|
|
2
|
+
import type { FillableFormFieldBinding, FillableFormGuidanceHint, FillableFormRecommendedTiming, StoredSecretFieldKey } from './types.js';
|
|
3
|
+
declare function collectVisibleFieldEvidence(fields: ReadonlyArray<FillableFormFieldBinding>, targetByRef: ReadonlyMap<string, TargetDescriptor>): string;
|
|
4
|
+
declare function collectBlockingValidationEvidence(fields: ReadonlyArray<FillableFormFieldBinding>, targetByRef: ReadonlyMap<string, TargetDescriptor>): string[];
|
|
5
|
+
declare function collectPassiveRequiredEvidence(fields: ReadonlyArray<FillableFormFieldBinding>, targetByRef: ReadonlyMap<string, TargetDescriptor>): string[];
|
|
6
|
+
declare function hasCorePaymentCardFields(fieldKeys: ReadonlySet<StoredSecretFieldKey>): boolean;
|
|
7
|
+
declare function looksLikePrimaryLoginForm(fieldKeys: ReadonlySet<StoredSecretFieldKey>): boolean;
|
|
8
|
+
declare function looksLikeStrongIdentityForm(fieldKeys: ReadonlySet<StoredSecretFieldKey>): boolean;
|
|
9
|
+
export declare function buildFillableFormGuidance(params: {
|
|
10
|
+
purpose: string;
|
|
11
|
+
recommendedTiming?: FillableFormRecommendedTiming;
|
|
12
|
+
fields: ReadonlyArray<FillableFormFieldBinding>;
|
|
13
|
+
targetByRef: ReadonlyMap<string, TargetDescriptor>;
|
|
14
|
+
}): FillableFormGuidanceHint;
|
|
15
|
+
export declare const __testRequestGuidance: {
|
|
16
|
+
collectVisibleFieldEvidence: typeof collectVisibleFieldEvidence;
|
|
17
|
+
collectBlockingValidationEvidence: typeof collectBlockingValidationEvidence;
|
|
18
|
+
collectPassiveRequiredEvidence: typeof collectPassiveRequiredEvidence;
|
|
19
|
+
hasCorePaymentCardFields: typeof hasCorePaymentCardFields;
|
|
20
|
+
looksLikePrimaryLoginForm: typeof looksLikePrimaryLoginForm;
|
|
21
|
+
looksLikeStrongIdentityForm: typeof looksLikeStrongIdentityForm;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=request-guidance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-guidance.d.ts","sourceRoot":"","sources":["../../src/secrets/request-guidance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAoCpB,iBAAS,2BAA2B,CAClC,MAAM,EAAE,aAAa,CAAC,wBAAwB,CAAC,EAC/C,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACjD,MAAM,CAYR;AAED,iBAAS,iCAAiC,CACxC,MAAM,EAAE,aAAa,CAAC,wBAAwB,CAAC,EAC/C,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACjD,MAAM,EAAE,CA+BV;AAED,iBAAS,8BAA8B,CACrC,MAAM,EAAE,aAAa,CAAC,wBAAwB,CAAC,EAC/C,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACjD,MAAM,EAAE,CAsBV;AAED,iBAAS,wBAAwB,CAAC,SAAS,EAAE,WAAW,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAEvF;AAED,iBAAS,yBAAyB,CAAC,SAAS,EAAE,WAAW,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAExF;AAED,iBAAS,2BAA2B,CAAC,SAAS,EAAE,WAAW,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAK1F;AAmBD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,6BAA6B,CAAC;IAClD,MAAM,EAAE,aAAa,CAAC,wBAAwB,CAAC,CAAC;IAChD,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACpD,GAAG,wBAAwB,CA4C3B;AAED,eAAO,MAAM,qBAAqB;;;;;;;CAOjC,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const PAYMENT_CARD_CORE_KEYS = new Set([
|
|
2
|
+
'pan',
|
|
3
|
+
'exp_month',
|
|
4
|
+
'exp_year',
|
|
5
|
+
'cvv',
|
|
6
|
+
]);
|
|
7
|
+
const HIGH_SIGNAL_IDENTITY_KEYS = new Set([
|
|
8
|
+
'document_number',
|
|
9
|
+
'date_of_birth',
|
|
10
|
+
'issue_date',
|
|
11
|
+
'expiry_date',
|
|
12
|
+
'issuing_country',
|
|
13
|
+
]);
|
|
14
|
+
const IMMEDIATE_HINT = 'This secret is likely needed now.';
|
|
15
|
+
const DEFER_HINT = 'Hold off on requesting this secret for now.';
|
|
16
|
+
const DEFER_RECHECK = 'Re-check only if submit or validation explicitly points back to this form.';
|
|
17
|
+
function humanizeFieldKey(fieldKey) {
|
|
18
|
+
return fieldKey.replace(/_/g, ' ');
|
|
19
|
+
}
|
|
20
|
+
function labelForField(field, target) {
|
|
21
|
+
return target?.displayLabel ?? target?.label ?? field.label ?? humanizeFieldKey(field.fieldKey);
|
|
22
|
+
}
|
|
23
|
+
function unique(values) {
|
|
24
|
+
return [...new Set(values)];
|
|
25
|
+
}
|
|
26
|
+
function collectVisibleFieldEvidence(fields, targetByRef) {
|
|
27
|
+
const labels = unique(fields
|
|
28
|
+
.map((field) => labelForField(field, targetByRef.get(field.targetRef)))
|
|
29
|
+
.filter((value) => value.length > 0));
|
|
30
|
+
if (labels.length === 0) {
|
|
31
|
+
return 'Matched fields are visible on the page.';
|
|
32
|
+
}
|
|
33
|
+
return `Visible matched fields: ${labels.join(', ')}.`;
|
|
34
|
+
}
|
|
35
|
+
function collectBlockingValidationEvidence(fields, targetByRef) {
|
|
36
|
+
const evidence = [];
|
|
37
|
+
const seenTargets = new Set();
|
|
38
|
+
for (const field of fields) {
|
|
39
|
+
if (seenTargets.has(field.targetRef)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
seenTargets.add(field.targetRef);
|
|
43
|
+
const target = targetByRef.get(field.targetRef);
|
|
44
|
+
const validation = target?.validation;
|
|
45
|
+
if (!validation) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const label = labelForField(field, target);
|
|
49
|
+
if (validation.message) {
|
|
50
|
+
evidence.push(`"${label}" already shows validation: ${validation.message}`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (validation.invalid) {
|
|
54
|
+
evidence.push(`"${label}" is currently marked invalid.`);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (validation.errorStyling) {
|
|
58
|
+
evidence.push(`"${label}" is already styled like an error.`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return evidence;
|
|
62
|
+
}
|
|
63
|
+
function collectPassiveRequiredEvidence(fields, targetByRef) {
|
|
64
|
+
const evidence = [];
|
|
65
|
+
const seenTargets = new Set();
|
|
66
|
+
for (const field of fields) {
|
|
67
|
+
if (seenTargets.has(field.targetRef)) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
seenTargets.add(field.targetRef);
|
|
71
|
+
const target = targetByRef.get(field.targetRef);
|
|
72
|
+
if (!target?.validation?.required) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (target.validation.invalid || target.validation.message || target.validation.errorStyling) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
evidence.push(`"${labelForField(field, target)}" is marked required.`);
|
|
79
|
+
}
|
|
80
|
+
return evidence;
|
|
81
|
+
}
|
|
82
|
+
function hasCorePaymentCardFields(fieldKeys) {
|
|
83
|
+
return [...PAYMENT_CARD_CORE_KEYS].every((fieldKey) => fieldKeys.has(fieldKey));
|
|
84
|
+
}
|
|
85
|
+
function looksLikePrimaryLoginForm(fieldKeys) {
|
|
86
|
+
return fieldKeys.has('password');
|
|
87
|
+
}
|
|
88
|
+
function looksLikeStrongIdentityForm(fieldKeys) {
|
|
89
|
+
const strongFieldCount = [...HIGH_SIGNAL_IDENTITY_KEYS].filter((fieldKey) => fieldKeys.has(fieldKey)).length;
|
|
90
|
+
return strongFieldCount > 0 || fieldKeys.size >= 3;
|
|
91
|
+
}
|
|
92
|
+
function immediateGuidance(why, evidence) {
|
|
93
|
+
return {
|
|
94
|
+
hint: IMMEDIATE_HINT,
|
|
95
|
+
why,
|
|
96
|
+
evidence: evidence.filter((value) => value.length > 0),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function deferGuidance(why, evidence) {
|
|
100
|
+
return {
|
|
101
|
+
hint: DEFER_HINT,
|
|
102
|
+
why,
|
|
103
|
+
recheckWhen: DEFER_RECHECK,
|
|
104
|
+
evidence: evidence.filter((value) => value.length > 0),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function buildFillableFormGuidance(params) {
|
|
108
|
+
const { purpose, recommendedTiming, fields, targetByRef } = params;
|
|
109
|
+
const visibleFieldEvidence = collectVisibleFieldEvidence(fields, targetByRef);
|
|
110
|
+
const blockingValidationEvidence = collectBlockingValidationEvidence(fields, targetByRef);
|
|
111
|
+
const passiveRequiredEvidence = collectPassiveRequiredEvidence(fields, targetByRef);
|
|
112
|
+
const fieldKeys = new Set(fields.map((field) => field.fieldKey));
|
|
113
|
+
if (blockingValidationEvidence.length > 0) {
|
|
114
|
+
return immediateGuidance('The page is already pointing at this form through active validation signals.', [visibleFieldEvidence, ...blockingValidationEvidence]);
|
|
115
|
+
}
|
|
116
|
+
if (purpose === 'payment_card' && hasCorePaymentCardFields(fieldKeys)) {
|
|
117
|
+
return immediateGuidance('This is the visible card form for the active checkout.', [
|
|
118
|
+
visibleFieldEvidence,
|
|
119
|
+
...passiveRequiredEvidence,
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
if (purpose === 'login' && looksLikePrimaryLoginForm(fieldKeys)) {
|
|
123
|
+
return immediateGuidance('This looks like the main login form needed to continue.', [
|
|
124
|
+
visibleFieldEvidence,
|
|
125
|
+
...passiveRequiredEvidence,
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
if (purpose === 'identity' && looksLikeStrongIdentityForm(fieldKeys)) {
|
|
129
|
+
return immediateGuidance('This looks like a full identity form rather than a one-off contact field.', [visibleFieldEvidence, ...passiveRequiredEvidence]);
|
|
130
|
+
}
|
|
131
|
+
const lateTimingEvidence = recommendedTiming === 'late' ? 'Matcher marked this form for late timing.' : '';
|
|
132
|
+
const noActiveBlockerEvidence = 'No matched field currently shows active validation that blocks progress.';
|
|
133
|
+
return deferGuidance('This form is visible, but there is not enough evidence yet that it is the blocker right now.', [visibleFieldEvidence, ...passiveRequiredEvidence, noActiveBlockerEvidence, lateTimingEvidence]);
|
|
134
|
+
}
|
|
135
|
+
export const __testRequestGuidance = {
|
|
136
|
+
collectVisibleFieldEvidence,
|
|
137
|
+
collectBlockingValidationEvidence,
|
|
138
|
+
collectPassiveRequiredEvidence,
|
|
139
|
+
hasCorePaymentCardFields,
|
|
140
|
+
looksLikePrimaryLoginForm,
|
|
141
|
+
looksLikeStrongIdentityForm,
|
|
142
|
+
};
|
package/dist/secrets/types.d.ts
CHANGED
|
@@ -45,6 +45,12 @@ export interface FillableFormFieldBinding {
|
|
|
45
45
|
required?: boolean;
|
|
46
46
|
valueHint?: ProtectedBindingValueHint;
|
|
47
47
|
}
|
|
48
|
+
export interface FillableFormGuidanceHint {
|
|
49
|
+
hint: string;
|
|
50
|
+
why: string;
|
|
51
|
+
recheckWhen?: string;
|
|
52
|
+
evidence: string[];
|
|
53
|
+
}
|
|
48
54
|
export interface FillableFormStoredSecretCandidate {
|
|
49
55
|
storedSecretRef: string;
|
|
50
56
|
kind: StoredSecretKind;
|
|
@@ -62,6 +68,7 @@ export interface PersistedFillableForm {
|
|
|
62
68
|
scopeRef?: string;
|
|
63
69
|
purpose: string;
|
|
64
70
|
recommendedTiming?: FillableFormRecommendedTiming;
|
|
71
|
+
guidance?: FillableFormGuidanceHint;
|
|
65
72
|
fields: FillableFormFieldBinding[];
|
|
66
73
|
storedSecretCandidates: FillableFormStoredSecretCandidate[];
|
|
67
74
|
observedAt: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/secrets/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/secrets/types.ts"],"names":[],"mappings":"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"}
|