@nuanu-ai/agentbrowse 0.2.49 → 0.2.50
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 +22 -7
- package/dist/agentpay-gateway.d.ts +1 -0
- package/dist/agentpay-gateway.d.ts.map +1 -1
- package/dist/agentpay-gateway.js +4 -1
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +46 -61
- package/dist/commands/action-acceptance.d.ts +3 -7
- package/dist/commands/action-acceptance.d.ts.map +1 -1
- package/dist/commands/action-acceptance.js +8 -25
- package/dist/commands/browser-status.d.ts +6 -0
- package/dist/commands/browser-status.d.ts.map +1 -0
- package/dist/commands/browser-status.js +228 -0
- package/dist/commands/close.d.ts.map +1 -1
- package/dist/commands/close.js +35 -30
- package/dist/commands/end-session.d.ts +1 -1
- package/dist/commands/end-session.d.ts.map +1 -1
- package/dist/commands/end-session.js +3 -1
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +32 -25
- 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 +12 -1
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +62 -92
- package/dist/commands/start-session.d.ts.map +1 -1
- package/dist/commands/start-session.js +15 -11
- package/dist/commands/status.d.ts +22 -2
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +36 -215
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -9
- package/dist/otel-exporter.d.ts.map +1 -1
- package/dist/otel-exporter.js +5 -11
- package/dist/run-store.d.ts +1 -1
- package/dist/run-store.d.ts.map +1 -1
- package/dist/run-store.js +3 -7
- package/dist/secrets/backend.d.ts +0 -1
- package/dist/secrets/backend.d.ts.map +1 -1
- package/dist/secrets/backend.js +0 -1
- package/dist/session-event-exporter.d.ts +1 -3
- package/dist/session-event-exporter.d.ts.map +1 -1
- package/dist/session-event-exporter.js +1 -14
- package/dist/sessions-backend.d.ts +20 -26
- package/dist/sessions-backend.d.ts.map +1 -1
- package/dist/sessions-backend.js +5 -5
- package/dist/solver/captcha-solver.d.ts.map +1 -1
- package/dist/solver/captcha-solver.js +12 -8
- package/dist/workflow-session-completion.d.ts +1 -1
- package/dist/workflow-session-completion.d.ts.map +1 -1
- package/dist/workflow-session-completion.js +23 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,12 @@ agentbrowse init ap_...
|
|
|
53
53
|
agentbrowse init ap_... --api-url https://your-project.supabase.co/functions/v1/api
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
Check AgentPay setup health and the authenticated agent profile:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
agentbrowse status
|
|
60
|
+
```
|
|
61
|
+
|
|
56
62
|
Launch browser and optionally navigate:
|
|
57
63
|
|
|
58
64
|
```bash
|
|
@@ -151,10 +157,10 @@ agentbrowse screenshot
|
|
|
151
157
|
agentbrowse screenshot --path ./checkout.png
|
|
152
158
|
```
|
|
153
159
|
|
|
154
|
-
Inspect or close the current session:
|
|
160
|
+
Inspect the launched browser or close the current workflow/browser session:
|
|
155
161
|
|
|
156
162
|
```bash
|
|
157
|
-
agentbrowse status
|
|
163
|
+
agentbrowse browser-status
|
|
158
164
|
agentbrowse end-session
|
|
159
165
|
agentbrowse close
|
|
160
166
|
```
|
|
@@ -207,21 +213,30 @@ overrides.
|
|
|
207
213
|
not an additional runtime config source
|
|
208
214
|
- all commands require AgentPay gateway configuration; prefer `agentbrowse init`
|
|
209
215
|
and use env vars only as runtime overrides
|
|
210
|
-
- `
|
|
216
|
+
- `status` checks AgentPay gateway health through `GET /api/agent/me` and
|
|
217
|
+
returns the authenticated agent profile on success
|
|
218
|
+
- `launch` is technical browser bootstrap only; it does not start a workflow session or observability export, but when the first working page is already known, prefer `launch <url>` so the workflow starts on the real page instead of `about:blank`
|
|
211
219
|
- `launch` fail-closes an older active workflow session before replacing the persisted browser context
|
|
212
220
|
- `start-session` starts the active workflow/run context on top of the current browser session
|
|
213
221
|
- `start-session` creates the backend product session through `POST /api/sessions`
|
|
222
|
+
- `start-session` exports the run root trace separately through `POST /api/observability/telemetry/traces`
|
|
214
223
|
- `start-session` may optionally attach `merchant_name` when the vendor is already known from the visible page or task context
|
|
215
224
|
- re-running `start-session` fail-closes the older active workflow session through `POST /api/sessions/:id/complete` before creating a new one
|
|
216
|
-
- page/runtime commands such as `navigate`, `observe`, `act`,
|
|
225
|
+
- page/runtime workflow commands such as `navigate`, `observe`, `act`,
|
|
226
|
+
`extract`, `screenshot`, `solve-captcha`, `request-secret`, `poll-secret`,
|
|
227
|
+
and `fill-secret` require that active product session; `launch` alone is not
|
|
228
|
+
enough
|
|
229
|
+
- `browser-status` is a browser/page/runtime diagnostic for a launched browser
|
|
230
|
+
session; it does not require an active workflow session
|
|
217
231
|
- use `navigate` for explicit later URL transitions inside an active workflow session, not as a mandatory first step when the initial page is already known
|
|
218
232
|
- `end-session` completes the active workflow session through `POST /api/sessions/:id/complete` and keeps the browser session alive
|
|
219
233
|
- normal successful workflow close-out should use `end-session`; `close` is browser teardown and cancels any still-active workflow session instead of completing it successfully
|
|
220
234
|
- `POST /api/sessions/:id/complete` is the only terminal session transition; ordinary `POST /api/sessions/:id/events` exports are non-terminal by contract
|
|
221
|
-
- the same `start-session` request also carries the current telemetry envelope in the same OTLP structure that browse-cli already exports today
|
|
222
|
-
- backend fan-out forwards that telemetry envelope through the existing telemetry ingest/index/forward path instead of inventing a new telemetry schema from product session fields
|
|
223
235
|
- after `start-session`, ordinary workflow-relevant command step exports go through `POST /api/sessions/:id/events`
|
|
224
|
-
-
|
|
236
|
+
- ordinary workflow-relevant command step traces export separately through `POST /api/observability/telemetry/traces`
|
|
237
|
+
- observability export is best-effort and must not rewrite the outcome of the product session mutation that ran before it
|
|
238
|
+
- `browser-status` stays local to the CLI as a diagnostic probe and does not
|
|
239
|
+
emit workflow session events
|
|
225
240
|
- `close` auto-cancels an active workflow session through `POST /api/sessions/:id/complete` before deleting the local browser session record
|
|
226
241
|
- protected requests are session-bound:
|
|
227
242
|
- `get-secrets-catalog(url?)` reads host-filtered catalog metadata through `GET /api/sessions/:id/secrets/catalog`
|
|
@@ -6,6 +6,7 @@ export declare function tryResolveAgentpayGatewayConfig(): AgentpayGatewayConfig
|
|
|
6
6
|
export declare function resolveAgentpayGatewayConfig(): AgentpayGatewayConfig;
|
|
7
7
|
export declare function applyAgentpayGatewayEnv(gateway: AgentpayGatewayConfig): void;
|
|
8
8
|
export declare function buildAgentpayTelemetryTracesUrl(apiUrl: string): string;
|
|
9
|
+
export declare function buildAgentpayAgentMeUrl(apiUrl: string): string;
|
|
9
10
|
export declare function buildAgentpaySessionsUrl(apiUrl: string): string;
|
|
10
11
|
export declare function buildAgentpaySessionUrl(apiUrl: string, sessionId: string): string;
|
|
11
12
|
export declare function buildAgentpaySessionSecretsCatalogUrl(apiUrl: string, sessionId: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentpay-gateway.d.ts","sourceRoot":"","sources":["../src/agentpay-gateway.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAgBD,wBAAgB,+BAA+B,IAAI,qBAAqB,GAAG,IAAI,CAgB9E;AAED,wBAAgB,4BAA4B,IAAI,qBAAqB,CAMpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAG5E;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/F;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzF;AAED,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/F;AAED,wBAAgB,oCAAoC,CAClD,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,
|
|
1
|
+
{"version":3,"file":"agentpay-gateway.d.ts","sourceRoot":"","sources":["../src/agentpay-gateway.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAgBD,wBAAgB,+BAA+B,IAAI,qBAAqB,GAAG,IAAI,CAgB9E;AAED,wBAAgB,4BAA4B,IAAI,qBAAqB,CAMpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAG5E;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/F;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzF;AAED,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/F;AAED,wBAAgB,oCAAoC,CAClD,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAI/E"}
|
package/dist/agentpay-gateway.js
CHANGED
|
@@ -38,7 +38,10 @@ export function applyAgentpayGatewayEnv(gateway) {
|
|
|
38
38
|
process.env.AGENTPAY_API_URL = gateway.apiUrl;
|
|
39
39
|
}
|
|
40
40
|
export function buildAgentpayTelemetryTracesUrl(apiUrl) {
|
|
41
|
-
return appendApiPath(apiUrl, '/telemetry/traces');
|
|
41
|
+
return appendApiPath(apiUrl, '/observability/telemetry/traces');
|
|
42
|
+
}
|
|
43
|
+
export function buildAgentpayAgentMeUrl(apiUrl) {
|
|
44
|
+
return appendApiPath(apiUrl, '/agent/me');
|
|
42
45
|
}
|
|
43
46
|
export function buildAgentpaySessionsUrl(apiUrl) {
|
|
44
47
|
return appendApiPath(apiUrl, '/sessions');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"act.d.ts","sourceRoot":"","sources":["../../src/commands/act.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAiCnD,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"act.d.ts","sourceRoot":"","sources":["../../src/commands/act.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAiCnD,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA8MxF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,CAAC;AA+R7B,wBAAsB,GAAG,CACvB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CA40Bf"}
|
package/dist/commands/act.js
CHANGED
|
@@ -32,7 +32,9 @@ function ensureValue(action, value) {
|
|
|
32
32
|
throw new Error(`Act value is required for action: ${action}`);
|
|
33
33
|
}
|
|
34
34
|
const MUTABLE_FIELD_REBIND_RETRY_DELAYS_MS = [0, 25, 50, 100];
|
|
35
|
-
const PARTIAL_SELECTION_PROGRESS_MESSAGE = 'Text entered
|
|
35
|
+
const PARTIAL_SELECTION_PROGRESS_MESSAGE = 'Text was entered and the related choice list remained open.';
|
|
36
|
+
const NO_OBSERVABLE_PROGRESS_MESSAGE = 'The action ran, but no visible page change was detected.';
|
|
37
|
+
const NO_OBSERVABLE_PROGRESS_REASON = 'No visible page or control state change was detected within the wait window.';
|
|
36
38
|
async function readExpandedState(locator) {
|
|
37
39
|
if (!locator) {
|
|
38
40
|
return null;
|
|
@@ -100,41 +102,32 @@ async function emitActPreflightFailure(params) {
|
|
|
100
102
|
action: params.action,
|
|
101
103
|
});
|
|
102
104
|
}
|
|
103
|
-
function reasonForNoObservableProgressDiagnosis(diagnosis) {
|
|
104
|
-
switch (diagnosis.kind) {
|
|
105
|
-
case 'validation-blocked':
|
|
106
|
-
return 'The page stayed in place and surfaced validation blockers after the action.';
|
|
107
|
-
case 'target-blocked':
|
|
108
|
-
return 'The target stayed in place but remained blocked or unchanged after the action.';
|
|
109
|
-
case 'overlay-blocked':
|
|
110
|
-
return 'A blocking overlay prevented the action from producing observable progress.';
|
|
111
|
-
case 'site-noop':
|
|
112
|
-
return 'The page stayed in place and did not expose any observable progress after the action.';
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
105
|
function describeActFailure(params) {
|
|
116
106
|
if (params.staleReason) {
|
|
117
107
|
const reason = params.staleReason === 'page-signature-mismatch'
|
|
118
|
-
? 'The page changed
|
|
108
|
+
? 'The page changed after the target was observed.'
|
|
119
109
|
: params.staleReason === 'dom-signature-mismatch'
|
|
120
|
-
? 'The
|
|
121
|
-
: 'The saved
|
|
110
|
+
? 'The element changed after the target was observed.'
|
|
111
|
+
: 'The saved target no longer points to a live element on the page.';
|
|
122
112
|
return {
|
|
113
|
+
error: 'stale_target',
|
|
123
114
|
outcomeType: 'binding_stale',
|
|
124
|
-
message: 'The
|
|
115
|
+
message: 'The saved target is outdated.',
|
|
125
116
|
reason,
|
|
126
117
|
};
|
|
127
118
|
}
|
|
128
|
-
if (params.
|
|
119
|
+
if (params.failureMessage === 'Act failed: no_observable_progress') {
|
|
129
120
|
return {
|
|
121
|
+
error: 'no_observable_progress',
|
|
130
122
|
outcomeType: 'blocked',
|
|
131
|
-
message:
|
|
132
|
-
reason:
|
|
123
|
+
message: NO_OBSERVABLE_PROGRESS_MESSAGE,
|
|
124
|
+
reason: NO_OBSERVABLE_PROGRESS_REASON,
|
|
133
125
|
};
|
|
134
126
|
}
|
|
135
127
|
const rawReason = params.failureMessage.replace(/^Act failed:\s*/, '');
|
|
136
128
|
if (rawReason === 'target_disabled') {
|
|
137
129
|
return {
|
|
130
|
+
error: 'target_disabled',
|
|
138
131
|
outcomeType: 'blocked',
|
|
139
132
|
message: 'The requested action cannot continue because the target is disabled.',
|
|
140
133
|
reason: 'The runtime resolved the target, but the browser marked it as disabled.',
|
|
@@ -142,6 +135,7 @@ function describeActFailure(params) {
|
|
|
142
135
|
}
|
|
143
136
|
if (rawReason === 'target_readonly') {
|
|
144
137
|
return {
|
|
138
|
+
error: 'target_readonly',
|
|
145
139
|
outcomeType: 'blocked',
|
|
146
140
|
message: 'The requested action cannot continue because the target is read-only.',
|
|
147
141
|
reason: 'The runtime resolved the target, but the browser marked it as read-only.',
|
|
@@ -149,42 +143,48 @@ function describeActFailure(params) {
|
|
|
149
143
|
}
|
|
150
144
|
if (rawReason === 'target_surface_inactive') {
|
|
151
145
|
return {
|
|
146
|
+
error: 'target_surface_inactive',
|
|
152
147
|
outcomeType: 'blocked',
|
|
153
148
|
message: 'The requested action cannot continue because the target surface is inactive.',
|
|
154
149
|
reason: 'The target belongs to a surface that is no longer active or available.',
|
|
155
150
|
};
|
|
156
151
|
}
|
|
157
152
|
return {
|
|
153
|
+
error: params.failureMessage,
|
|
158
154
|
outcomeType: 'blocked',
|
|
159
155
|
message: 'The requested action could not be completed.',
|
|
160
156
|
reason: rawReason,
|
|
161
157
|
};
|
|
162
158
|
}
|
|
163
159
|
export { BROWSE_ACTIONS, isBrowseAction };
|
|
164
|
-
function
|
|
160
|
+
function hasMeaningfulNoObservableProgressObservations(observations) {
|
|
161
|
+
return Boolean(observations &&
|
|
162
|
+
(observations.visibleMessages.length > 0 ||
|
|
163
|
+
observations.invalidFields.length > 0 ||
|
|
164
|
+
observations.targetState));
|
|
165
|
+
}
|
|
166
|
+
function redactNoObservableProgressObservations(observations) {
|
|
165
167
|
return {
|
|
166
|
-
|
|
167
|
-
...(
|
|
168
|
-
...(diagnosis.messages.length > 0
|
|
168
|
+
...(observations.targetState ? { targetState: observations.targetState } : {}),
|
|
169
|
+
...(observations.visibleMessages.length > 0
|
|
169
170
|
? {
|
|
170
|
-
|
|
171
|
-
|
|
171
|
+
visibleMessagesRedacted: true,
|
|
172
|
+
visibleMessageCount: observations.visibleMessages.length,
|
|
172
173
|
}
|
|
173
174
|
: {}),
|
|
174
|
-
...(
|
|
175
|
+
...(observations.invalidFields.length > 0
|
|
175
176
|
? {
|
|
176
177
|
invalidFieldsRedacted: true,
|
|
177
|
-
invalidFieldCount:
|
|
178
|
-
}
|
|
179
|
-
: {}),
|
|
180
|
-
...(diagnosis.blockingOverlays.length > 0
|
|
181
|
-
? {
|
|
182
|
-
blockingOverlaysRedacted: true,
|
|
183
|
-
blockingOverlayCount: diagnosis.blockingOverlays.length,
|
|
178
|
+
invalidFieldCount: observations.invalidFields.length,
|
|
184
179
|
}
|
|
185
180
|
: {}),
|
|
186
181
|
};
|
|
187
182
|
}
|
|
183
|
+
function sanitizePublicAttempts(attempts) {
|
|
184
|
+
return attempts.filter((attempt) => !attempt.startsWith('stale.') &&
|
|
185
|
+
!attempt.startsWith('no-progress.diagnosis:') &&
|
|
186
|
+
attempt !== 'outcome.partial-progress:selection-not-complete');
|
|
187
|
+
}
|
|
188
188
|
function buildActArtifactManifest(params) {
|
|
189
189
|
if ('suppressed' in params.artifacts) {
|
|
190
190
|
return {
|
|
@@ -505,7 +505,7 @@ export async function act(session, targetRef, action, value) {
|
|
|
505
505
|
let recoveredProgressProbe = null;
|
|
506
506
|
let staleReason = null;
|
|
507
507
|
let progressProbe = null;
|
|
508
|
-
let
|
|
508
|
+
let noProgressObservations = null;
|
|
509
509
|
let partialProgressResult = null;
|
|
510
510
|
let liveTarget = target;
|
|
511
511
|
let trace = {
|
|
@@ -875,10 +875,7 @@ export async function act(session, targetRef, action, value) {
|
|
|
875
875
|
else {
|
|
876
876
|
attempts.push(`acceptance.failed:${finalProgressProbe.policy}`);
|
|
877
877
|
attempts.push('no-progress.detected');
|
|
878
|
-
|
|
879
|
-
if (noProgressDiagnosis) {
|
|
880
|
-
attempts.push(`no-progress.diagnosis:${noProgressDiagnosis.kind}`);
|
|
881
|
-
}
|
|
878
|
+
noProgressObservations = await diagnoseNoObservableProgress(page, finalProgressProbe.locator);
|
|
882
879
|
throw new Error('no_observable_progress');
|
|
883
880
|
}
|
|
884
881
|
}
|
|
@@ -898,10 +895,7 @@ export async function act(session, targetRef, action, value) {
|
|
|
898
895
|
finalProgressProbe.beforeContextHash === afterContextHash &&
|
|
899
896
|
!locatorStateChanged(finalProgressProbe.beforeLocator, afterLocatorObservation)) {
|
|
900
897
|
attempts.push('no-progress.detected');
|
|
901
|
-
|
|
902
|
-
if (noProgressDiagnosis) {
|
|
903
|
-
attempts.push(`no-progress.diagnosis:${noProgressDiagnosis.kind}`);
|
|
904
|
-
}
|
|
898
|
+
noProgressObservations = await diagnoseNoObservableProgress(page, finalProgressProbe.locator);
|
|
905
899
|
throw new Error('no_observable_progress');
|
|
906
900
|
}
|
|
907
901
|
}
|
|
@@ -911,9 +905,6 @@ export async function act(session, targetRef, action, value) {
|
|
|
911
905
|
requestedAction,
|
|
912
906
|
probe: finalProgressProbe,
|
|
913
907
|
});
|
|
914
|
-
if (partialProgressResult) {
|
|
915
|
-
attempts.push('outcome.partial-progress:selection-not-complete');
|
|
916
|
-
}
|
|
917
908
|
}
|
|
918
909
|
}
|
|
919
910
|
else if (recoveredProgressProbe) {
|
|
@@ -921,9 +912,6 @@ export async function act(session, targetRef, action, value) {
|
|
|
921
912
|
requestedAction,
|
|
922
913
|
probe: recoveredProgressProbe,
|
|
923
914
|
});
|
|
924
|
-
if (partialProgressResult) {
|
|
925
|
-
attempts.push('outcome.partial-progress:selection-not-complete');
|
|
926
|
-
}
|
|
927
915
|
}
|
|
928
916
|
}
|
|
929
917
|
if (resolvedBy === 'playwright-locator') {
|
|
@@ -964,7 +952,7 @@ export async function act(session, targetRef, action, value) {
|
|
|
964
952
|
resolvedBy,
|
|
965
953
|
locatorStrategy,
|
|
966
954
|
pageRef: finalPageRef,
|
|
967
|
-
attempts,
|
|
955
|
+
attempts: sanitizePublicAttempts(attempts),
|
|
968
956
|
popup: Boolean(capturedPopup),
|
|
969
957
|
overlayHandled: attempts.includes('overlay.dismissed'),
|
|
970
958
|
iframe: Boolean(target.framePath?.length),
|
|
@@ -1023,18 +1011,16 @@ export async function act(session, targetRef, action, value) {
|
|
|
1023
1011
|
}
|
|
1024
1012
|
}
|
|
1025
1013
|
if (failureMessage) {
|
|
1026
|
-
if (failureMessage === 'Act failed: no_observable_progress' && noProgressDiagnosis) {
|
|
1027
|
-
failureMessage = `Act failed: no_observable_progress (${noProgressDiagnosis.kind})`;
|
|
1028
|
-
}
|
|
1029
1014
|
const failureContract = describeActFailure({
|
|
1030
1015
|
failureMessage,
|
|
1031
1016
|
staleReason,
|
|
1032
|
-
diagnosis: noProgressDiagnosis,
|
|
1033
1017
|
});
|
|
1034
1018
|
const protectedExposure = getProtectedExposure(session, currentPageRef);
|
|
1035
|
-
const
|
|
1036
|
-
?
|
|
1037
|
-
|
|
1019
|
+
const outputObservations = hasMeaningfulNoObservableProgressObservations(noProgressObservations)
|
|
1020
|
+
? protectedExposure
|
|
1021
|
+
? redactNoObservableProgressObservations(noProgressObservations)
|
|
1022
|
+
: noProgressObservations
|
|
1023
|
+
: undefined;
|
|
1038
1024
|
const artifactManifestId = persistActArtifactManifestBestEffort(runId, actStep?.stepId, failureArtifacts ?? null);
|
|
1039
1025
|
captureStepSnapshotBestEffort({
|
|
1040
1026
|
session,
|
|
@@ -1063,7 +1049,7 @@ export async function act(session, targetRef, action, value) {
|
|
|
1063
1049
|
});
|
|
1064
1050
|
await exportRunStepToOtlpHttpJsonBestEffort(runId, actStep?.stepId);
|
|
1065
1051
|
outputFailure({
|
|
1066
|
-
error:
|
|
1052
|
+
error: failureContract.error,
|
|
1067
1053
|
outcomeType: failureContract.outcomeType,
|
|
1068
1054
|
message: failureContract.message,
|
|
1069
1055
|
reason: failureContract.reason,
|
|
@@ -1073,15 +1059,14 @@ export async function act(session, targetRef, action, value) {
|
|
|
1073
1059
|
value: actionValue,
|
|
1074
1060
|
pageRef: currentPageRef,
|
|
1075
1061
|
locatorStrategy,
|
|
1076
|
-
attempts,
|
|
1062
|
+
attempts: sanitizePublicAttempts(attempts),
|
|
1077
1063
|
popup: attempts.includes('popup-captured'),
|
|
1078
1064
|
overlayHandled: attempts.includes('overlay.dismissed'),
|
|
1079
1065
|
iframe: Boolean(target.framePath?.length),
|
|
1080
1066
|
jsFallback: attempts.some((attempt) => attempt.startsWith('locator.evaluate.')),
|
|
1081
1067
|
durationMs: Date.now() - startedAt,
|
|
1082
1068
|
staleTarget: Boolean(staleReason),
|
|
1083
|
-
|
|
1084
|
-
diagnosis: outputDiagnosis ?? undefined,
|
|
1069
|
+
observations: outputObservations,
|
|
1085
1070
|
artifacts: failureArtifacts,
|
|
1086
1071
|
metrics: session.runtime?.metrics,
|
|
1087
1072
|
});
|
|
@@ -45,16 +45,12 @@ export type AcceptanceProbeResult = {
|
|
|
45
45
|
afterPageObservation: PageObservation | null;
|
|
46
46
|
polls: number;
|
|
47
47
|
};
|
|
48
|
-
export type
|
|
49
|
-
|
|
50
|
-
messages: string[];
|
|
48
|
+
export type NoObservableProgressObservations = {
|
|
49
|
+
visibleMessages: string[];
|
|
51
50
|
invalidFields: string[];
|
|
52
|
-
blockingOverlays: string[];
|
|
53
51
|
targetState?: {
|
|
54
52
|
disabled?: boolean;
|
|
55
|
-
ariaDisabled?: boolean;
|
|
56
53
|
readonly?: boolean;
|
|
57
|
-
centerHitSelf?: boolean;
|
|
58
54
|
};
|
|
59
55
|
};
|
|
60
56
|
export declare function rankLocatorCandidates(candidates: ReadonlyArray<NonNullable<ReturnType<typeof getTarget>>['locatorCandidates'][number]>, action: BrowseAction): import("../runtime-state.js").LocatorCandidate[];
|
|
@@ -76,7 +72,7 @@ export declare function locatorStateChanged(before: LocatorStateObservation | nu
|
|
|
76
72
|
export declare function pageObservationChanged(before: PageObservation | null, after: PageObservation | null): boolean;
|
|
77
73
|
export declare function genericClickObservationChanged(before: PageObservation | null, after: PageObservation | null): boolean;
|
|
78
74
|
export declare function submitObservationChanged(before: PageObservation | null, after: PageObservation | null): boolean;
|
|
79
|
-
export declare function diagnoseNoObservableProgress(page: Page, locator: Locator): Promise<
|
|
75
|
+
export declare function diagnoseNoObservableProgress(page: Page, locator: Locator): Promise<NoObservableProgressObservations | null>;
|
|
80
76
|
export declare function createAcceptanceProbe(args: {
|
|
81
77
|
session: BrowseSession;
|
|
82
78
|
page: Page;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-acceptance.d.ts","sourceRoot":"","sources":["../../src/commands/action-acceptance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAc,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,KAAK,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9F,KAAK,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;AAEjF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,WAAW,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC1D,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACrC,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvC,UAAU,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC9C,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iBAAiB,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAClD,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,EAAE,CAAC;IACxB,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,oBAAoB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"action-acceptance.d.ts","sourceRoot":"","sources":["../../src/commands/action-acceptance.ts"],"names":[],"mappings":"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"}
|
|
@@ -1446,39 +1446,22 @@ export async function diagnoseNoObservableProgress(page, locator) {
|
|
|
1446
1446
|
const invalidFields = Array.isArray(pageSignals.invalidFields)
|
|
1447
1447
|
? pageSignals.invalidFields.filter((value) => typeof value === 'string')
|
|
1448
1448
|
: [];
|
|
1449
|
-
const blockingOverlays = Array.isArray(pageSignals.blockingOverlays)
|
|
1450
|
-
? pageSignals.blockingOverlays.filter((value) => typeof value === 'string')
|
|
1451
|
-
: [];
|
|
1452
1449
|
const rawTargetState = targetState && typeof targetState === 'object' && !Array.isArray(targetState)
|
|
1453
1450
|
? targetState
|
|
1454
1451
|
: undefined;
|
|
1455
|
-
const
|
|
1452
|
+
const disabled = rawTargetState &&
|
|
1453
|
+
(Boolean(rawTargetState.disabled) || Boolean(rawTargetState.ariaDisabled));
|
|
1454
|
+
const readonly = rawTargetState ? Boolean(rawTargetState.readonly) : false;
|
|
1455
|
+
const normalizedTargetState = disabled || readonly
|
|
1456
1456
|
? {
|
|
1457
|
-
disabled:
|
|
1458
|
-
|
|
1459
|
-
readonly: Boolean(rawTargetState.readonly),
|
|
1460
|
-
centerHitSelf: Boolean(rawTargetState.centerHitSelf),
|
|
1457
|
+
...(disabled ? { disabled: true } : {}),
|
|
1458
|
+
...(readonly ? { readonly: true } : {}),
|
|
1461
1459
|
}
|
|
1462
1460
|
: undefined;
|
|
1463
|
-
const effectiveBlockingOverlays = normalizedTargetState?.centerHitSelf ? [] : blockingOverlays;
|
|
1464
|
-
let kind = 'site-noop';
|
|
1465
|
-
if (invalidFields.length > 0) {
|
|
1466
|
-
kind = 'validation-blocked';
|
|
1467
|
-
}
|
|
1468
|
-
else if (normalizedTargetState?.disabled ||
|
|
1469
|
-
normalizedTargetState?.ariaDisabled ||
|
|
1470
|
-
normalizedTargetState?.readonly) {
|
|
1471
|
-
kind = 'target-blocked';
|
|
1472
|
-
}
|
|
1473
|
-
else if (effectiveBlockingOverlays.length > 0) {
|
|
1474
|
-
kind = 'overlay-blocked';
|
|
1475
|
-
}
|
|
1476
1461
|
return {
|
|
1477
|
-
|
|
1478
|
-
messages,
|
|
1462
|
+
visibleMessages: messages,
|
|
1479
1463
|
invalidFields,
|
|
1480
|
-
|
|
1481
|
-
targetState: normalizedTargetState,
|
|
1464
|
+
...(normalizedTargetState ? { targetState: normalizedTargetState } : {}),
|
|
1482
1465
|
};
|
|
1483
1466
|
}
|
|
1484
1467
|
async function resolveTargetLocatorForRead(page, target, surface, action = 'click') {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-status.d.ts","sourceRoot":"","sources":["../../src/commands/browser-status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA+LjD,wBAAsB,aAAa,IAAI,OAAO,CAAC,YAAY,CAAC,CAiH3D"}
|