@nuanu-ai/agentbrowse 0.2.7 → 0.2.8
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 +36 -8
- package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
- package/dist/agentpay-stagehand-llm.js +5 -1
- package/dist/commands/act.d.ts +6 -2
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +840 -55
- package/dist/commands/act.test-harness.d.ts +19 -0
- package/dist/commands/act.test-harness.d.ts.map +1 -0
- package/dist/commands/act.test-harness.js +245 -0
- package/dist/commands/action-acceptance.d.ts +90 -0
- package/dist/commands/action-acceptance.d.ts.map +1 -0
- package/dist/commands/action-acceptance.js +1411 -0
- package/dist/commands/action-artifacts.d.ts +33 -0
- package/dist/commands/action-artifacts.d.ts.map +1 -0
- package/dist/commands/action-artifacts.js +104 -0
- package/dist/commands/action-execution-guards.d.ts +5 -0
- package/dist/commands/action-execution-guards.d.ts.map +1 -0
- package/dist/commands/action-execution-guards.js +3 -0
- package/dist/commands/action-executor-helpers.d.ts +21 -0
- package/dist/commands/action-executor-helpers.d.ts.map +1 -0
- package/dist/commands/action-executor-helpers.js +242 -0
- package/dist/commands/action-executor.d.ts +12 -0
- package/dist/commands/action-executor.d.ts.map +1 -0
- package/dist/commands/action-executor.js +45 -0
- package/dist/commands/action-fallbacks.d.ts +6 -0
- package/dist/commands/action-fallbacks.d.ts.map +1 -0
- package/dist/commands/action-fallbacks.js +43 -0
- package/dist/commands/action-value-projection.d.ts +32 -0
- package/dist/commands/action-value-projection.d.ts.map +1 -0
- package/dist/commands/action-value-projection.js +151 -0
- package/dist/commands/browse-actions.d.ts +4 -0
- package/dist/commands/browse-actions.d.ts.map +1 -0
- package/dist/commands/browse-actions.js +4 -0
- package/dist/commands/captcha-solve.d.ts.map +1 -1
- package/dist/commands/captcha-solve.js +13 -3
- package/dist/commands/click-action-executor.d.ts +10 -0
- package/dist/commands/click-action-executor.d.ts.map +1 -0
- package/dist/commands/click-action-executor.js +68 -0
- package/dist/commands/create-intent.d.ts +6 -0
- package/dist/commands/create-intent.d.ts.map +1 -0
- package/dist/commands/create-intent.js +75 -0
- package/dist/commands/datepicker-action-executor.d.ts +12 -0
- package/dist/commands/datepicker-action-executor.d.ts.map +1 -0
- package/dist/commands/datepicker-action-executor.js +218 -0
- package/dist/commands/descriptor-validation.d.ts +27 -0
- package/dist/commands/descriptor-validation.d.ts.map +1 -0
- package/dist/commands/descriptor-validation.js +333 -0
- package/dist/commands/extract-scope-resolution.d.ts +20 -0
- package/dist/commands/extract-scope-resolution.d.ts.map +1 -0
- package/dist/commands/extract-scope-resolution.js +100 -0
- package/dist/commands/extract-stagehand-executor.d.ts +17 -0
- package/dist/commands/extract-stagehand-executor.d.ts.map +1 -0
- package/dist/commands/extract-stagehand-executor.js +18 -0
- package/dist/commands/extract.d.ts +3 -2
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +256 -39
- package/dist/commands/fill-secret.d.ts +7 -0
- package/dist/commands/fill-secret.d.ts.map +1 -0
- package/dist/commands/fill-secret.js +371 -0
- package/dist/commands/get-secrets-catalog.d.ts +6 -0
- package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
- package/dist/commands/get-secrets-catalog.js +23 -0
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +41 -7
- package/dist/commands/navigate.d.ts +2 -1
- package/dist/commands/navigate.d.ts.map +1 -1
- package/dist/commands/navigate.js +49 -12
- package/dist/commands/observe-inventory.d.ts +109 -0
- package/dist/commands/observe-inventory.d.ts.map +1 -0
- package/dist/commands/observe-inventory.js +2837 -0
- package/dist/commands/observe-persistence.d.ts +14 -0
- package/dist/commands/observe-persistence.d.ts.map +1 -0
- package/dist/commands/observe-persistence.js +170 -0
- package/dist/commands/observe-projection.d.ts +84 -0
- package/dist/commands/observe-projection.d.ts.map +1 -0
- package/dist/commands/observe-projection.js +140 -0
- package/dist/commands/observe-protected.d.ts +5 -0
- package/dist/commands/observe-protected.d.ts.map +1 -0
- package/dist/commands/observe-protected.js +18 -0
- package/dist/commands/observe-semantics.d.ts +10 -0
- package/dist/commands/observe-semantics.d.ts.map +1 -0
- package/dist/commands/observe-semantics.js +338 -0
- package/dist/commands/observe-stagehand.d.ts +48 -0
- package/dist/commands/observe-stagehand.d.ts.map +1 -0
- package/dist/commands/observe-stagehand.js +105 -0
- package/dist/commands/observe-surfaces.d.ts +9 -0
- package/dist/commands/observe-surfaces.d.ts.map +1 -0
- package/dist/commands/observe-surfaces.js +195 -0
- package/dist/commands/observe.d.ts +47 -1
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +173 -20
- package/dist/commands/observe.test-harness.d.ts +67 -0
- package/dist/commands/observe.test-harness.d.ts.map +1 -0
- package/dist/commands/observe.test-harness.js +107 -0
- package/dist/commands/poll-intent.d.ts +6 -0
- package/dist/commands/poll-intent.d.ts.map +1 -0
- package/dist/commands/poll-intent.js +57 -0
- package/dist/commands/screenshot.d.ts +2 -1
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/commands/screenshot.js +44 -12
- package/dist/commands/select-action-executor.d.ts +10 -0
- package/dist/commands/select-action-executor.d.ts.map +1 -0
- package/dist/commands/select-action-executor.js +91 -0
- package/dist/commands/semantic-observe.d.ts +24 -0
- package/dist/commands/semantic-observe.d.ts.map +1 -0
- package/dist/commands/semantic-observe.js +344 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +75 -2
- package/dist/commands/structured-grid-action-executor.d.ts +3 -0
- package/dist/commands/structured-grid-action-executor.d.ts.map +1 -0
- package/dist/commands/structured-grid-action-executor.js +4 -0
- package/dist/commands/target-resolution.d.ts +4 -0
- package/dist/commands/target-resolution.d.ts.map +1 -0
- package/dist/commands/target-resolution.js +33 -0
- package/dist/commands/text-input-action-executor.d.ts +5 -0
- package/dist/commands/text-input-action-executor.d.ts.map +1 -0
- package/dist/commands/text-input-action-executor.js +116 -0
- package/dist/commands/user-actionable.d.ts +4 -0
- package/dist/commands/user-actionable.d.ts.map +1 -0
- package/dist/commands/user-actionable.js +95 -0
- package/dist/control-semantics.d.ts +29 -0
- package/dist/control-semantics.d.ts.map +1 -0
- package/dist/control-semantics.js +299 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +95 -32
- package/dist/output.d.ts +14 -2
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +17 -29
- package/dist/playwright-runtime.d.ts +35 -0
- package/dist/playwright-runtime.d.ts.map +1 -0
- package/dist/playwright-runtime.js +224 -0
- package/dist/runtime-resolution.d.ts +9 -0
- package/dist/runtime-resolution.d.ts.map +1 -0
- package/dist/runtime-resolution.js +19 -0
- package/dist/runtime-state.d.ts +217 -0
- package/dist/runtime-state.d.ts.map +1 -0
- package/dist/runtime-state.js +629 -0
- package/dist/secrets/backend.d.ts +32 -0
- package/dist/secrets/backend.d.ts.map +1 -0
- package/dist/secrets/backend.js +169 -0
- package/dist/secrets/catalog-applicability.d.ts +5 -0
- package/dist/secrets/catalog-applicability.d.ts.map +1 -0
- package/dist/secrets/catalog-applicability.js +59 -0
- package/dist/secrets/catalog-sync.d.ts +14 -0
- package/dist/secrets/catalog-sync.d.ts.map +1 -0
- package/dist/secrets/catalog-sync.js +35 -0
- package/dist/secrets/field-policy.d.ts +3 -0
- package/dist/secrets/field-policy.d.ts.map +1 -0
- package/dist/secrets/field-policy.js +3 -0
- package/dist/secrets/fill-ordering.d.ts +11 -0
- package/dist/secrets/fill-ordering.d.ts.map +1 -0
- package/dist/secrets/fill-ordering.js +44 -0
- package/dist/secrets/form-matcher.d.ts +60 -0
- package/dist/secrets/form-matcher.d.ts.map +1 -0
- package/dist/secrets/form-matcher.js +596 -0
- package/dist/secrets/intent-output.d.ts +11 -0
- package/dist/secrets/intent-output.d.ts.map +1 -0
- package/dist/secrets/intent-output.js +64 -0
- package/dist/secrets/mock-agentpay-backend.d.ts +13 -0
- package/dist/secrets/mock-agentpay-backend.d.ts.map +1 -0
- package/dist/secrets/mock-agentpay-backend.js +87 -0
- package/dist/secrets/mock-agentpay-cabinet.d.ts +43 -0
- package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -0
- package/dist/secrets/mock-agentpay-cabinet.js +195 -0
- package/dist/secrets/protected-artifact-guard.d.ts +25 -0
- package/dist/secrets/protected-artifact-guard.d.ts.map +1 -0
- package/dist/secrets/protected-artifact-guard.js +26 -0
- package/dist/secrets/protected-bindings.d.ts +10 -0
- package/dist/secrets/protected-bindings.d.ts.map +1 -0
- package/dist/secrets/protected-bindings.js +17 -0
- package/dist/secrets/protected-field-values.d.ts +13 -0
- package/dist/secrets/protected-field-values.d.ts.map +1 -0
- package/dist/secrets/protected-field-values.js +100 -0
- package/dist/secrets/protected-fill.d.ts +47 -0
- package/dist/secrets/protected-fill.d.ts.map +1 -0
- package/dist/secrets/protected-fill.js +512 -0
- package/dist/secrets/types.d.ts +84 -0
- package/dist/secrets/types.d.ts.map +1 -0
- package/dist/secrets/types.js +27 -0
- package/dist/session.d.ts +22 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +74 -2
- package/dist/solver/browser-launcher.d.ts.map +1 -1
- package/dist/solver/browser-launcher.js +6 -3
- package/dist/stagehand-runtime.d.ts +4 -0
- package/dist/stagehand-runtime.d.ts.map +1 -0
- package/dist/stagehand-runtime.js +10 -0
- package/dist/stagehand.d.ts +0 -5
- package/dist/stagehand.d.ts.map +1 -1
- package/dist/stagehand.js +0 -6
- package/package.json +5 -2
package/dist/commands/extract.js
CHANGED
|
@@ -1,59 +1,276 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* browse extract
|
|
2
|
+
* browse extract '<schema-json>' [scopeRef] — Extract structured data from the page or a stored scope.
|
|
3
3
|
*/
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
import { saveSession } from '../session.js';
|
|
6
|
+
import { getSurface, getTarget, markSurfaceLifecycle, markTargetLifecycle, setCurrentPage, } from '../runtime-state.js';
|
|
7
|
+
import { outputContractFailure, outputJSON } from '../output.js';
|
|
8
|
+
import { connectPlaywright, disconnectPlaywright, resolvePageByRef as resolvePlaywrightPageByRef, syncSessionPage, } from '../playwright-runtime.js';
|
|
9
|
+
import { normalizePageSignature } from './descriptor-validation.js';
|
|
10
|
+
import { resolveScopedExtractContext } from './extract-scope-resolution.js';
|
|
11
|
+
import { executeStagehandExtract } from './extract-stagehand-executor.js';
|
|
12
|
+
function buildSchemaValue(descriptor) {
|
|
13
|
+
if (descriptor === 'string')
|
|
14
|
+
return z.string();
|
|
15
|
+
if (descriptor === 'number')
|
|
16
|
+
return z.number();
|
|
17
|
+
if (descriptor === 'boolean')
|
|
18
|
+
return z.boolean();
|
|
19
|
+
if (Array.isArray(descriptor)) {
|
|
20
|
+
const itemDescriptor = descriptor[0];
|
|
21
|
+
return z.array(itemDescriptor === undefined ? z.unknown() : buildSchemaValue(itemDescriptor));
|
|
22
|
+
}
|
|
23
|
+
if (typeof descriptor === 'object' && descriptor !== null) {
|
|
24
|
+
const shape = {};
|
|
25
|
+
for (const [key, value] of Object.entries(descriptor)) {
|
|
26
|
+
shape[key] = buildSchemaValue(value);
|
|
27
|
+
}
|
|
28
|
+
return z.object(shape);
|
|
29
|
+
}
|
|
30
|
+
return z.unknown();
|
|
31
|
+
}
|
|
13
32
|
function buildSchema(descriptor) {
|
|
14
|
-
|
|
33
|
+
return buildSchemaValue(descriptor);
|
|
34
|
+
}
|
|
35
|
+
function describeSchema(descriptor, prefix) {
|
|
36
|
+
const lines = [];
|
|
15
37
|
for (const [key, value] of Object.entries(descriptor)) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
else if (value === 'boolean')
|
|
21
|
-
shape[key] = z.boolean();
|
|
22
|
-
else if (typeof value === 'object' && value !== null) {
|
|
23
|
-
shape[key] = buildSchema(value);
|
|
38
|
+
const fieldPath = prefix ? `${prefix}.${key}` : key;
|
|
39
|
+
if (value === 'string' || value === 'number' || value === 'boolean') {
|
|
40
|
+
lines.push(`${fieldPath}: ${value}`);
|
|
41
|
+
continue;
|
|
24
42
|
}
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
if (Array.isArray(value)) {
|
|
44
|
+
const itemDescriptor = value[0];
|
|
45
|
+
if (itemDescriptor === 'string' || itemDescriptor === 'number' || itemDescriptor === 'boolean') {
|
|
46
|
+
lines.push(`${fieldPath}[]: ${itemDescriptor}`);
|
|
47
|
+
}
|
|
48
|
+
else if (typeof itemDescriptor === 'object' && itemDescriptor !== null && !Array.isArray(itemDescriptor)) {
|
|
49
|
+
lines.push(...describeSchema(itemDescriptor, `${fieldPath}[]`));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
lines.push(`${fieldPath}[]: unknown`);
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
27
55
|
}
|
|
56
|
+
if (typeof value === 'object' && value !== null) {
|
|
57
|
+
lines.push(...describeSchema(value, fieldPath));
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
lines.push(`${fieldPath}: unknown`);
|
|
28
61
|
}
|
|
29
|
-
return
|
|
62
|
+
return lines;
|
|
63
|
+
}
|
|
64
|
+
function buildInstruction(schemaDescriptor, scopeRef) {
|
|
65
|
+
const fields = describeSchema(schemaDescriptor);
|
|
66
|
+
const scopeNote = scopeRef
|
|
67
|
+
? 'Only inspect the provided scoped container, not the full page.'
|
|
68
|
+
: 'Inspect the current page.';
|
|
69
|
+
return [
|
|
70
|
+
'Extract structured data that is explicitly visible in the current DOM state.',
|
|
71
|
+
scopeNote,
|
|
72
|
+
'Return only the fields defined by the schema and do not infer missing values.',
|
|
73
|
+
`Fields: ${fields.join('; ') || 'none'}.`,
|
|
74
|
+
].join(' ');
|
|
30
75
|
}
|
|
31
|
-
|
|
32
|
-
|
|
76
|
+
function canUseTargetAsExtractScope(target) {
|
|
77
|
+
if (target.capability === 'informational') {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
if (target.capability === 'scope') {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
const kind = (target.kind ?? '').toLowerCase();
|
|
84
|
+
const role = (target.semantics?.role ?? '').toLowerCase();
|
|
85
|
+
const scopeLikeKinds = new Set([
|
|
86
|
+
'card',
|
|
87
|
+
'article',
|
|
88
|
+
'section',
|
|
89
|
+
'row',
|
|
90
|
+
'grid',
|
|
91
|
+
'gridcell',
|
|
92
|
+
'listitem',
|
|
93
|
+
'dialog',
|
|
94
|
+
'tabpanel',
|
|
95
|
+
'region',
|
|
96
|
+
'form',
|
|
97
|
+
'group',
|
|
98
|
+
]);
|
|
99
|
+
const leafInteractiveKinds = new Set(['input', 'textarea', 'select', 'option', 'button', 'link', 'combobox']);
|
|
100
|
+
const leafInteractiveRoles = new Set(['textbox', 'combobox', 'option', 'menuitem', 'button', 'link']);
|
|
101
|
+
const iframeFieldLike = Boolean(target.framePath?.length) &&
|
|
102
|
+
(target.allowedActions.includes('fill') ||
|
|
103
|
+
target.allowedActions.includes('type') ||
|
|
104
|
+
target.allowedActions.includes('select') ||
|
|
105
|
+
['input', 'textarea', 'select', 'combobox'].includes(kind) ||
|
|
106
|
+
['textbox', 'combobox'].includes(role));
|
|
107
|
+
if (target.allowedActions.length === 0) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (iframeFieldLike) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
if (target.allowedActions.includes('fill') ||
|
|
114
|
+
target.allowedActions.includes('type') ||
|
|
115
|
+
target.allowedActions.includes('select')) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
if (leafInteractiveKinds.has(kind) || leafInteractiveRoles.has(role)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return Boolean(target.surfaceRef) || scopeLikeKinds.has(kind) || scopeLikeKinds.has(role);
|
|
122
|
+
}
|
|
123
|
+
export async function extract(session, schemaJson, scopeRef) {
|
|
124
|
+
let schemaDescriptor;
|
|
33
125
|
try {
|
|
34
|
-
|
|
126
|
+
schemaDescriptor = JSON.parse(schemaJson);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return outputContractFailure({
|
|
130
|
+
error: 'invalid_extract_schema',
|
|
131
|
+
outcomeType: 'blocked',
|
|
132
|
+
message: 'Extraction could not start because the schema JSON is invalid.',
|
|
133
|
+
reason: 'The provided schema argument is not valid JSON.',
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
const schema = buildSchema(schemaDescriptor);
|
|
137
|
+
const instruction = buildInstruction(schemaDescriptor, scopeRef);
|
|
138
|
+
const targetScope = scopeRef ? getTarget(session, scopeRef) : null;
|
|
139
|
+
const surfaceScope = !targetScope && scopeRef ? getSurface(session, scopeRef) : null;
|
|
140
|
+
const scopeTarget = targetScope ?? surfaceScope;
|
|
141
|
+
const pageRef = scopeTarget?.pageRef ?? session.runtime?.currentPageRef ?? 'p0';
|
|
142
|
+
if (scopeRef && !scopeTarget) {
|
|
143
|
+
return outputContractFailure({
|
|
144
|
+
error: 'unknown_scope_ref',
|
|
145
|
+
outcomeType: 'blocked',
|
|
146
|
+
message: 'Extraction could not start because the requested scopeRef is unknown.',
|
|
147
|
+
reason: `No live scope target matches scopeRef ${scopeRef}.`,
|
|
148
|
+
scopeRef,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (scopeTarget && scopeTarget.lifecycle !== 'live') {
|
|
152
|
+
return outputContractFailure({
|
|
153
|
+
error: 'stale_extract_scope',
|
|
154
|
+
outcomeType: 'binding_stale',
|
|
155
|
+
message: 'Extraction could not start because the requested scope is no longer live.',
|
|
156
|
+
reason: `Scope ${scopeRef} is ${scopeTarget.lifecycle}${scopeTarget.lifecycleReason ? ` because ${scopeTarget.lifecycleReason}` : ''}.`,
|
|
157
|
+
scopeRef,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (targetScope && !canUseTargetAsExtractScope(targetScope)) {
|
|
161
|
+
return outputContractFailure({
|
|
162
|
+
error: 'invalid_extract_scope',
|
|
163
|
+
outcomeType: 'unsupported',
|
|
164
|
+
message: 'Extraction cannot use the requested target as a scope.',
|
|
165
|
+
reason: `Target ${scopeRef} is a leaf control, not an extractable scope container.`,
|
|
166
|
+
scopeRef,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
let browser = null;
|
|
170
|
+
let failureMessage = null;
|
|
171
|
+
let cleanupScopedExtract = null;
|
|
172
|
+
let staleScope = false;
|
|
173
|
+
let staleReason = null;
|
|
174
|
+
try {
|
|
175
|
+
browser = await connectPlaywright(session.cdpUrl);
|
|
35
176
|
}
|
|
36
177
|
catch (err) {
|
|
37
|
-
|
|
178
|
+
return outputContractFailure({
|
|
179
|
+
error: 'browser_connection_failed',
|
|
180
|
+
outcomeType: 'blocked',
|
|
181
|
+
message: 'Extraction could not start because AgentBrowse failed to connect to the browser.',
|
|
182
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
183
|
+
scopeRef,
|
|
184
|
+
pageRef,
|
|
185
|
+
});
|
|
38
186
|
}
|
|
39
187
|
try {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
188
|
+
const sourcePage = await resolvePlaywrightPageByRef(browser, session, pageRef);
|
|
189
|
+
let page = sourcePage;
|
|
190
|
+
let scopedResolution = null;
|
|
191
|
+
const { url, title } = await syncSessionPage(session, pageRef, sourcePage);
|
|
192
|
+
if (scopeTarget?.pageSignature && normalizePageSignature(url) !== scopeTarget.pageSignature) {
|
|
193
|
+
staleScope = true;
|
|
194
|
+
staleReason = 'page-signature-mismatch';
|
|
195
|
+
throw new Error('stale_scope_target_page_signature_changed');
|
|
47
196
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
197
|
+
let effectiveSelector;
|
|
198
|
+
if (scopeTarget) {
|
|
199
|
+
try {
|
|
200
|
+
scopedResolution = await resolveScopedExtractContext({
|
|
201
|
+
page: sourcePage,
|
|
202
|
+
scopeTarget,
|
|
203
|
+
validateDomSignature: Boolean(targetScope),
|
|
204
|
+
});
|
|
205
|
+
cleanupScopedExtract = scopedResolution.cleanup;
|
|
206
|
+
page = scopedResolution.page;
|
|
207
|
+
effectiveSelector = scopedResolution.selector;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
if (error instanceof Error &&
|
|
211
|
+
error.message === 'stale_scope_target_dom_signature_changed') {
|
|
212
|
+
staleScope = true;
|
|
213
|
+
staleReason = 'dom-signature-mismatch';
|
|
214
|
+
}
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
53
217
|
}
|
|
218
|
+
setCurrentPage(session, pageRef);
|
|
219
|
+
const execution = await executeStagehandExtract({
|
|
220
|
+
session,
|
|
221
|
+
instruction,
|
|
222
|
+
schema,
|
|
223
|
+
page,
|
|
224
|
+
selector: effectiveSelector,
|
|
225
|
+
degradationReason: scopedResolution?.degraded
|
|
226
|
+
? scopedResolution.degradationReason
|
|
227
|
+
: undefined,
|
|
228
|
+
});
|
|
229
|
+
saveSession(session);
|
|
230
|
+
outputJSON({
|
|
231
|
+
success: true,
|
|
232
|
+
...execution,
|
|
233
|
+
pageRef,
|
|
234
|
+
scopeRef,
|
|
235
|
+
metrics: session.runtime?.metrics,
|
|
236
|
+
url,
|
|
237
|
+
title,
|
|
238
|
+
});
|
|
54
239
|
}
|
|
55
240
|
catch (err) {
|
|
56
|
-
|
|
57
|
-
|
|
241
|
+
if (staleScope && scopeRef) {
|
|
242
|
+
if (targetScope) {
|
|
243
|
+
markTargetLifecycle(session, scopeRef, 'stale', staleReason ?? 'unknown');
|
|
244
|
+
}
|
|
245
|
+
else if (surfaceScope) {
|
|
246
|
+
markSurfaceLifecycle(session, scopeRef, 'stale', staleReason ?? 'unknown');
|
|
247
|
+
}
|
|
248
|
+
saveSession(session);
|
|
249
|
+
}
|
|
250
|
+
failureMessage = `Extract failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
251
|
+
}
|
|
252
|
+
finally {
|
|
253
|
+
if (cleanupScopedExtract) {
|
|
254
|
+
await cleanupScopedExtract().catch(() => undefined);
|
|
255
|
+
}
|
|
256
|
+
if (browser) {
|
|
257
|
+
disconnectPlaywright(browser);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (failureMessage) {
|
|
261
|
+
outputContractFailure({
|
|
262
|
+
error: staleScope ? 'stale_extract_scope' : 'extract_failed',
|
|
263
|
+
outcomeType: staleScope ? 'binding_stale' : 'blocked',
|
|
264
|
+
message: staleScope
|
|
265
|
+
? 'Extraction failed because the requested scope became stale.'
|
|
266
|
+
: 'Extraction failed.',
|
|
267
|
+
reason: staleScope && scopeRef
|
|
268
|
+
? `${failureMessage} (${scopeRef} marked stale: ${staleReason ?? 'stale'})`
|
|
269
|
+
: failureMessage.replace(/^Extract failed:\s*/, ''),
|
|
270
|
+
scopeRef,
|
|
271
|
+
pageRef,
|
|
272
|
+
staleScope,
|
|
273
|
+
staleReason: staleReason ?? undefined,
|
|
274
|
+
});
|
|
58
275
|
}
|
|
59
276
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* browse fill-secret <fillRef> <intentId> — Fill protected fields from a cached one-time secret payload
|
|
3
|
+
* using the persisted plan and deterministic browser execution.
|
|
4
|
+
*/
|
|
5
|
+
import type { BrowseSession } from '../session.js';
|
|
6
|
+
export declare function fillSecret(session: BrowseSession, fillRef: string, intentId: string): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=fill-secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill-secret.d.ts","sourceRoot":"","sources":["../../src/commands/fill-secret.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA8InD,wBAAsB,UAAU,CAC9B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAmUf"}
|