@nuanu-ai/agentbrowse 0.2.12 → 0.2.13

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.
Files changed (50) hide show
  1. package/README.md +5 -0
  2. package/dist/agentpay-stagehand-llm.d.ts +16 -0
  3. package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
  4. package/dist/agentpay-stagehand-llm.js +35 -10
  5. package/dist/commands/act.d.ts.map +1 -1
  6. package/dist/commands/act.js +16 -15
  7. package/dist/commands/action-acceptance.d.ts +1 -0
  8. package/dist/commands/action-acceptance.d.ts.map +1 -1
  9. package/dist/commands/action-acceptance.js +77 -1
  10. package/dist/commands/extract-snapshot-sanitizer.d.ts +2 -0
  11. package/dist/commands/extract-snapshot-sanitizer.d.ts.map +1 -0
  12. package/dist/commands/extract-snapshot-sanitizer.js +65 -0
  13. package/dist/commands/extract-stagehand-executor.d.ts.map +1 -1
  14. package/dist/commands/extract-stagehand-executor.js +33 -3
  15. package/dist/commands/extract.d.ts.map +1 -1
  16. package/dist/commands/extract.js +29 -0
  17. package/dist/commands/launch.js +0 -7
  18. package/dist/commands/observe-projection.d.ts +1 -3
  19. package/dist/commands/observe-projection.d.ts.map +1 -1
  20. package/dist/commands/observe-projection.js +110 -3
  21. package/dist/commands/observe.d.ts.map +1 -1
  22. package/dist/commands/observe.js +28 -11
  23. package/dist/playwright-runtime.d.ts +3 -1
  24. package/dist/playwright-runtime.d.ts.map +1 -1
  25. package/dist/playwright-runtime.js +42 -2
  26. package/dist/secrets/fill-ordering.d.ts +1 -2
  27. package/dist/secrets/fill-ordering.d.ts.map +1 -1
  28. package/dist/secrets/fill-ordering.js +0 -3
  29. package/dist/secrets/form-matcher.d.ts.map +1 -1
  30. package/dist/secrets/form-matcher.js +0 -9
  31. package/dist/secrets/types.d.ts +0 -9
  32. package/dist/secrets/types.d.ts.map +1 -1
  33. package/dist/solver/browser-launcher.d.ts.map +1 -1
  34. package/dist/solver/browser-launcher.js +492 -55
  35. package/dist/solver/captcha-detector.d.ts.map +1 -1
  36. package/dist/solver/captcha-detector.js +187 -12
  37. package/dist/solver/captcha-runtime.d.ts.map +1 -1
  38. package/dist/solver/captcha-runtime.js +8 -0
  39. package/dist/solver/captcha-solver.d.ts +11 -1
  40. package/dist/solver/captcha-solver.d.ts.map +1 -1
  41. package/dist/solver/captcha-solver.js +11 -4
  42. package/dist/solver/turnstile-challenge.d.ts +3 -0
  43. package/dist/solver/turnstile-challenge.d.ts.map +1 -0
  44. package/dist/solver/turnstile-challenge.js +173 -0
  45. package/dist/solver/types.d.ts +10 -8
  46. package/dist/solver/types.d.ts.map +1 -1
  47. package/package.json +1 -1
  48. package/dist/secrets/request-guidance.d.ts +0 -24
  49. package/dist/secrets/request-guidance.d.ts.map +0 -1
  50. package/dist/secrets/request-guidance.js +0 -142
package/README.md CHANGED
@@ -63,6 +63,10 @@ agentbrowse extract '{"productName":"string","price":"number"}'
63
63
  agentbrowse extract '{"shipping":"string"}' t21
64
64
  ```
65
65
 
66
+ `observe` is the tool for visible interactive controls and refs.
67
+ `extract` is for bounded structured page data; do not use it to enumerate
68
+ buttons, links, inputs, or refs when `observe` already provides that inventory.
69
+
66
70
  Solve captcha when the active session supports it:
67
71
 
68
72
  ```bash
@@ -117,6 +121,7 @@ Default verification for this package is no longer unit-only:
117
121
 
118
122
  - `pnpm --filter @nuanu-ai/agentbrowse test` includes local fixture browser integration coverage for runtime and extract flows
119
123
  - the default suite also covers one explicit Stagehand-assisted observe fallback plus launch/session smoke at the command boundary
124
+ - the e2e portion binds local fixture servers on `127.0.0.1`; sandboxed runners that forbid loopback `listen()` calls can fail early with `listen EPERM`, so rerun the same command outside the sandbox before treating it as a product regression
120
125
 
121
126
  See package docs:
122
127
 
@@ -1,5 +1,21 @@
1
1
  import { LLMClient, toJsonSchema, type CreateChatCompletionOptions, type LLMParsedResponse, type LLMResponse } from '@browserbasehq/stagehand';
2
2
  import type { AgentpayGatewayConfig } from './agentpay-gateway.js';
3
+ export declare class AgentpayStructuredOutputTruncatedError extends Error {
4
+ readonly status: number;
5
+ readonly provider?: string;
6
+ readonly model?: string;
7
+ readonly finishReason?: string;
8
+ readonly maxOutputTokens?: number;
9
+ readonly completionTokens?: number;
10
+ constructor(message: string, params: {
11
+ status: number;
12
+ provider?: string;
13
+ model?: string;
14
+ finishReason?: string;
15
+ maxOutputTokens?: number;
16
+ completionTokens?: number;
17
+ });
18
+ }
3
19
  export declare class AgentpayStagehandLlmClient extends LLMClient {
4
20
  private readonly gateway;
5
21
  type: "agentpay";
@@ -1 +1 @@
1
- {"version":3,"file":"agentpay-stagehand-llm.d.ts","sourceRoot":"","sources":["../src/agentpay-stagehand-llm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,YAAY,EACZ,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAqDnE,qBAAa,0BAA2B,SAAQ,SAAS;IAI3C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,IAAI,EAAG,UAAU,CAAU;IAC3B,aAAa,KAAM;gBAEU,OAAO,EAAE,qBAAqB;IAKrD,oBAAoB,CAAC,CAAC,EAC1B,IAAI,EAAE,2BAA2B,GAAG;QAClC,OAAO,EAAE;YACP,cAAc,EAAE;gBACd,IAAI,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;aAC5C,CAAC;SACH,CAAC;KACH,GACA,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAC1B,oBAAoB,CAAC,CAAC,GAAG,WAAW,EAAE,IAAI,EAAE,2BAA2B,GAAG,OAAO,CAAC,CAAC,CAAC;CA2F3F;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,qBAAqB,GAC7B,0BAA0B,CAE5B"}
1
+ {"version":3,"file":"agentpay-stagehand-llm.d.ts","sourceRoot":"","sources":["../src/agentpay-stagehand-llm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,YAAY,EACZ,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAmBnE,qBAAa,sCAAuC,SAAQ,KAAK;IAC/D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;gBAGjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;CAWJ;AAsDD,qBAAa,0BAA2B,SAAQ,SAAS;IAI3C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,IAAI,EAAG,UAAU,CAAU;IAC3B,aAAa,KAAM;gBAEU,OAAO,EAAE,qBAAqB;IAKrD,oBAAoB,CAAC,CAAC,EAC1B,IAAI,EAAE,2BAA2B,GAAG;QAClC,OAAO,EAAE;YACP,cAAc,EAAE;gBACd,IAAI,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;aAC5C,CAAC;SACH,CAAC;KACH,GACA,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAC1B,oBAAoB,CAAC,CAAC,GAAG,WAAW,EAAE,IAAI,EAAE,2BAA2B,GAAG,OAAO,CAAC,CAAC,CAAC;CA8F3F;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,qBAAqB,GAC7B,0BAA0B,CAE5B"}
@@ -1,4 +1,28 @@
1
1
  import { LLMClient, toJsonSchema, } from '@browserbasehq/stagehand';
2
+ export class AgentpayStructuredOutputTruncatedError extends Error {
3
+ status;
4
+ provider;
5
+ model;
6
+ finishReason;
7
+ maxOutputTokens;
8
+ completionTokens;
9
+ constructor(message, params) {
10
+ super(message);
11
+ this.name = 'AgentpayStructuredOutputTruncatedError';
12
+ this.status = params.status;
13
+ this.provider = params.provider;
14
+ this.model = params.model;
15
+ this.finishReason = params.finishReason;
16
+ this.maxOutputTokens = params.maxOutputTokens;
17
+ this.completionTokens = params.completionTokens;
18
+ }
19
+ }
20
+ function readString(value) {
21
+ return typeof value === 'string' && value.trim().length > 0 ? value : undefined;
22
+ }
23
+ function readNumber(value) {
24
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
25
+ }
2
26
  function gatewayBaseUrl(gateway) {
3
27
  return gateway.apiUrl.replace(/\/$/, '');
4
28
  }
@@ -105,22 +129,23 @@ export class AgentpayStagehandLlmClient extends LLMClient {
105
129
  }
106
130
  if (!response.ok) {
107
131
  const message = typeof json.error === 'string' ? json.error : `HTTP ${response.status}`;
132
+ const structuredError = json;
133
+ if (structuredError.error_code === 'structured_output_truncated') {
134
+ throw new AgentpayStructuredOutputTruncatedError(`AgentPay LLM gateway error (${response.status}): ${message}`, {
135
+ status: response.status,
136
+ provider: readString(structuredError.provider),
137
+ model: readString(structuredError.model),
138
+ finishReason: readString(structuredError.finish_reason),
139
+ maxOutputTokens: readNumber(structuredError.max_output_tokens),
140
+ completionTokens: readNumber(structuredError.completion_tokens),
141
+ });
142
+ }
108
143
  const error = new Error(`AgentPay LLM gateway error (${response.status}): ${message}`);
109
144
  error.name = isRetryableStatus(response.status) ? 'RetryableHttpError' : 'HttpError';
110
145
  throw error;
111
146
  }
112
147
  return json;
113
148
  });
114
- logger({
115
- category: 'llm',
116
- message: 'agentpay backend structured completion finished',
117
- level: 2,
118
- auxiliary: {
119
- provider: { value: result.provider, type: 'string' },
120
- model: { value: result.model, type: 'string' },
121
- purpose: { value: resolvePurpose(options), type: 'string' },
122
- },
123
- });
124
149
  return {
125
150
  data: result.data,
126
151
  usage: result.usage,
@@ -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;AAmCnD,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAqHxF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,CAAC;AAuV7B,wBAAsB,GAAG,CACvB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAknBf"}
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;AAmCnD,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAqHxF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,CAAC;AAoV7B,wBAAsB,GAAG,CACvB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAsnBf"}
@@ -302,18 +302,15 @@ async function capturePopupIfOpened(session, beforePages, afterPages, currentPag
302
302
  const popup = afterPages.find((page) => !beforePages.includes(page));
303
303
  if (!popup)
304
304
  return null;
305
- const [url, title] = await Promise.all([
306
- Promise.resolve(popup.url()),
307
- popup.title().catch(() => ''),
308
- ]);
309
305
  const page = registerPage(session, {
310
- url,
311
- title,
312
306
  openerPageRef: currentPageRef,
313
- makeCurrent: true,
307
+ makeCurrent: false,
314
308
  });
315
309
  attempts.push('popup-captured');
316
- return page.pageRef;
310
+ return {
311
+ page,
312
+ popup,
313
+ };
317
314
  }
318
315
  async function waitForPopup(context) {
319
316
  try {
@@ -686,15 +683,19 @@ export async function act(session, targetRef, action, value) {
686
683
  }
687
684
  const discoveredPage = popup ?? latePage;
688
685
  const afterPages = discoveredPage ? [...beforePages, discoveredPage] : listPages(browser);
689
- const popupPageRef = await capturePopupIfOpened(session, beforePages, afterPages, target.pageRef, attempts);
690
- const finalPageRef = popupPageRef ?? target.pageRef;
691
- currentPageRef = finalPageRef;
692
- if (popupPageRef) {
693
- const popupPage = await resolvePageByRef(browser, session, popupPageRef);
694
- await syncSessionPage(session, popupPageRef, popupPage);
686
+ const capturedPopup = await capturePopupIfOpened(session, beforePages, afterPages, target.pageRef, attempts);
687
+ let finalPageRef = target.pageRef;
688
+ if (capturedPopup) {
689
+ await syncSessionPage(session, capturedPopup.page.pageRef, capturedPopup.popup, {
690
+ settleTimeoutMs: 1_500,
691
+ });
692
+ setCurrentPage(session, capturedPopup.page.pageRef);
693
+ finalPageRef = capturedPopup.page.pageRef;
694
+ currentPageRef = finalPageRef;
695
695
  }
696
696
  else {
697
697
  const syncedPage = await syncSessionPage(session, target.pageRef, page);
698
+ currentPageRef = target.pageRef;
698
699
  if (startingPageUrl && syncedPage.url && syncedPage.url !== startingPageUrl) {
699
700
  clearProtectedExposure(session, target.pageRef);
700
701
  }
@@ -763,7 +764,7 @@ export async function act(session, targetRef, action, value) {
763
764
  locatorStrategy,
764
765
  pageRef: finalPageRef,
765
766
  attempts,
766
- popup: Boolean(popupPageRef),
767
+ popup: Boolean(capturedPopup),
767
768
  overlayHandled: attempts.includes('overlay.dismissed'),
768
769
  iframe: Boolean(target.framePath?.length),
769
770
  jsFallback: attempts.some((attempt) => attempt.startsWith('locator.evaluate.')),
@@ -10,6 +10,7 @@ export type PageObservation = {
10
10
  contentHash: string | null;
11
11
  structureHash: string | null;
12
12
  submitSignalHash: string | null;
13
+ validationBlockerCount: number;
13
14
  };
14
15
  type TargetStateKey = 'selected' | 'checked' | 'expanded' | 'pressed' | 'current' | 'focused';
15
16
  type LocatorStateObservation = Partial<Record<TargetStateKey, string | boolean>>;
@@ -1 +1 @@
1
- {"version":3,"file":"action-acceptance.d.ts","sourceRoot":"","sources":["../../src/commands/action-acceptance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"action-acceptance.d.ts","sourceRoot":"","sources":["../../src/commands/action-acceptance.ts"],"names":[],"mappings":"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"}
@@ -334,6 +334,70 @@ const PAGE_OBSERVATION_SCRIPT = String.raw `(() => {
334
334
 
335
335
  return items.join('|');
336
336
  };
337
+ const validationSummary = () => {
338
+ const fieldSelectors =
339
+ 'input, textarea, select, [role="textbox"], [contenteditable="true"], [aria-invalid="true"]';
340
+ const validationMessageSelectors = [
341
+ '[role="alert"]',
342
+ '[aria-live="assertive"]',
343
+ '[aria-live="polite"]',
344
+ '.error',
345
+ '.errors',
346
+ '.invalid-feedback',
347
+ '.form-error',
348
+ '.warning',
349
+ '[data-testid*="error"]',
350
+ '[data-testid*="warning"]',
351
+ ];
352
+ const validationTextRe =
353
+ /(?:required|invalid|incorrect|too\s+(?:short|long)|must|error|format|please\s+(?:enter|select|choose|fill)|невер|ошиб|обязател|заполн|введите|укажите|выберите|долж|нужно|формат|цифр|символ)/i;
354
+ const items = [];
355
+
356
+ for (const element of Array.from(document.querySelectorAll(fieldSelectors))) {
357
+ if (!(element instanceof HTMLElement) || !isVisible(element)) {
358
+ continue;
359
+ }
360
+
361
+ const ariaInvalid = element.getAttribute('aria-invalid') === 'true';
362
+ const htmlInvalid =
363
+ element instanceof HTMLInputElement ||
364
+ element instanceof HTMLTextAreaElement ||
365
+ element instanceof HTMLSelectElement
366
+ ? !element.checkValidity()
367
+ : false;
368
+ if (!ariaInvalid && !htmlInvalid) {
369
+ continue;
370
+ }
371
+
372
+ const label =
373
+ normalizeText(element.getAttribute('aria-label')) ||
374
+ normalizeText(element.getAttribute('name')) ||
375
+ normalizeText(element.getAttribute('placeholder')) ||
376
+ normalizeText(element.id);
377
+ items.push('field:' + (label || 'invalid'));
378
+ if (items.length >= 12) {
379
+ return items.join('|');
380
+ }
381
+ }
382
+
383
+ for (const element of Array.from(document.querySelectorAll(validationMessageSelectors.join(', ')))) {
384
+ if (!(element instanceof HTMLElement) || !isVisible(element)) {
385
+ continue;
386
+ }
387
+
388
+ const text = normalizeText(element.textContent || '');
389
+ if (!text || !validationTextRe.test(text)) {
390
+ continue;
391
+ }
392
+
393
+ items.push('message:' + text.slice(0, 160));
394
+ if (items.length >= 12) {
395
+ break;
396
+ }
397
+ }
398
+
399
+ return items.join('|');
400
+ };
337
401
 
338
402
  const body = document.body;
339
403
  if (!body) {
@@ -341,6 +405,7 @@ const PAGE_OBSERVATION_SCRIPT = String.raw `(() => {
341
405
  content: '',
342
406
  structure: '',
343
407
  submitSignals: '',
408
+ validationBlockerCount: 0,
344
409
  };
345
410
  }
346
411
 
@@ -356,10 +421,12 @@ const PAGE_OBSERVATION_SCRIPT = String.raw `(() => {
356
421
  const frames = frameSummary();
357
422
  const headings = headingSummary();
358
423
  const processing = processingSummary();
424
+ const validation = validationSummary();
359
425
  return {
360
426
  content: [attrs, text, controls, dialogs, frames].join('\n'),
361
427
  structure: [attrs, stableControls, dialogs, frames, headings].join('\n'),
362
428
  submitSignals: [processing, dialogs, frames, headings, stableControls].join('\n'),
429
+ validationBlockerCount: validation ? validation.split('|').length : 0,
363
430
  };
364
431
  })()`;
365
432
  const NO_PROGRESS_PAGE_SIGNALS_SCRIPT = String.raw `(() => {
@@ -673,12 +740,18 @@ export async function capturePageObservation(page) {
673
740
  const contentSnapshot = typeof snapshot === 'string' ? snapshot : (snapshot?.content ?? '');
674
741
  const structureSnapshot = typeof snapshot === 'string' ? '' : (snapshot?.structure ?? '');
675
742
  const submitSignalSnapshot = typeof snapshot === 'string' ? '' : (snapshot?.submitSignals ?? '');
743
+ const validationBlockerCount = typeof snapshot === 'string'
744
+ ? 0
745
+ : typeof snapshot?.validationBlockerCount === 'number'
746
+ ? snapshot.validationBlockerCount
747
+ : 0;
676
748
  return {
677
749
  url: page.url(),
678
750
  title: await page.title().catch(() => ''),
679
751
  contentHash: contentSnapshot ? hashText(contentSnapshot) : null,
680
752
  structureHash: structureSnapshot ? hashText(structureSnapshot) : null,
681
753
  submitSignalHash: submitSignalSnapshot ? hashText(submitSignalSnapshot) : null,
754
+ validationBlockerCount,
682
755
  };
683
756
  }
684
757
  async function readLocatorText(locator) {
@@ -1084,6 +1157,9 @@ export function submitObservationChanged(before, after) {
1084
1157
  before.structureHash !== after.structureHash) {
1085
1158
  return true;
1086
1159
  }
1160
+ if (before.validationBlockerCount > 0 && after.validationBlockerCount === 0) {
1161
+ return true;
1162
+ }
1087
1163
  return false;
1088
1164
  }
1089
1165
  export async function diagnoseNoObservableProgress(page, locator) {
@@ -1147,7 +1223,7 @@ export async function diagnoseNoObservableProgress(page, locator) {
1147
1223
  : undefined;
1148
1224
  const effectiveBlockingOverlays = normalizedTargetState?.centerHitSelf ? [] : blockingOverlays;
1149
1225
  let kind = 'site-noop';
1150
- if (messages.length > 0 || invalidFields.length > 0) {
1226
+ if (invalidFields.length > 0) {
1151
1227
  kind = 'validation-blocked';
1152
1228
  }
1153
1229
  else if (normalizedTargetState?.disabled ||
@@ -0,0 +1,2 @@
1
+ export declare function sanitizeExtractSnapshot(snapshot: string): string;
2
+ //# sourceMappingURL=extract-snapshot-sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-snapshot-sanitizer.d.ts","sourceRoot":"","sources":["../../src/commands/extract-snapshot-sanitizer.ts"],"names":[],"mappings":"AAwEA,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQhE"}
@@ -0,0 +1,65 @@
1
+ const SUSPICIOUS_LINE_LENGTH = 220;
2
+ const SUSPICIOUS_TOKEN_LENGTH = 120;
3
+ const MIN_MACHINE_PUNCTUATION_RATIO = 0.18;
4
+ const SCRIPT_MARKERS = [
5
+ /\bwindow\./i,
6
+ /\bdocument\./i,
7
+ /\bwebpack/i,
8
+ /\b__next_data__\b/i,
9
+ /\bfunction\b/,
10
+ /\bconst\b/,
11
+ /\blet\b/,
12
+ /\bvar\b/,
13
+ /\breturn\b/,
14
+ /=>/,
15
+ /\bJSON\.parse\(/,
16
+ ];
17
+ function countMatches(value, pattern) {
18
+ return value.match(pattern)?.length ?? 0;
19
+ }
20
+ function extractLineContent(line) {
21
+ const quotedContent = line.match(/"([\s\S]*)"$/);
22
+ if (quotedContent?.[1]) {
23
+ return quotedContent[1];
24
+ }
25
+ return line.replace(/^\s*\[[^\]]+\]\s*/, '').trim();
26
+ }
27
+ function punctuationRatio(value) {
28
+ if (!value.length) {
29
+ return 0;
30
+ }
31
+ const punctuationChars = countMatches(value, /[{}[\]();,:=<>\\/]/g);
32
+ return punctuationChars / value.length;
33
+ }
34
+ function longestTokenLength(value) {
35
+ return value.split(/\s+/).reduce((longest, token) => Math.max(longest, token.length), 0);
36
+ }
37
+ function looksLikeJsonBlob(value) {
38
+ const braces = countMatches(value, /[{}[\]]/g);
39
+ const quotes = countMatches(value, /"/g);
40
+ const colons = countMatches(value, /:/g);
41
+ const commas = countMatches(value, /,/g);
42
+ return braces >= 6 && quotes >= 6 && colons >= 3 && commas >= 2;
43
+ }
44
+ function looksLikeScriptBlob(value) {
45
+ return SCRIPT_MARKERS.some((pattern) => pattern.test(value));
46
+ }
47
+ function isLikelyMachineBlob(value) {
48
+ const longLine = value.length >= SUSPICIOUS_LINE_LENGTH;
49
+ const longToken = longestTokenLength(value) >= SUSPICIOUS_TOKEN_LENGTH;
50
+ const densePunctuation = punctuationRatio(value) >= MIN_MACHINE_PUNCTUATION_RATIO;
51
+ const escapedNoise = countMatches(value, /(?:\\u[0-9a-f]{4}|\\\\|\\")/gi) >= 4;
52
+ const structuredNoise = looksLikeJsonBlob(value) || looksLikeScriptBlob(value) || escapedNoise;
53
+ if (!structuredNoise) {
54
+ return false;
55
+ }
56
+ return longLine || longToken || densePunctuation;
57
+ }
58
+ export function sanitizeExtractSnapshot(snapshot) {
59
+ const lines = snapshot.split(/\r?\n/);
60
+ const sanitized = lines.filter((line) => {
61
+ const content = extractLineContent(line);
62
+ return !isLikelyMachineBlob(content);
63
+ });
64
+ return sanitized.some((line) => line.trim()) ? sanitized.join('\n') : snapshot;
65
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"extract-stagehand-executor.d.ts","sourceRoot":"","sources":["../../src/commands/extract-stagehand-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAA8B,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG9F,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GAAG;IAC1D,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,mBAAmB,CAAC;CACjC,CAAC;AAEF,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAerC"}
1
+ {"version":3,"file":"extract-stagehand-executor.d.ts","sourceRoot":"","sources":["../../src/commands/extract-stagehand-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAA8B,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAI9F,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GAAG;IAC1D,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,mBAAmB,CAAC;CACjC,CAAC;AAaF,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAsDrC"}
@@ -1,14 +1,44 @@
1
+ import { extract as runExtract } from '@browserbasehq/stagehand/lib/inference.js';
2
+ import { v3Logger } from '@browserbasehq/stagehand/lib/v3/logger.js';
3
+ import { captureHybridSnapshot } from '@browserbasehq/stagehand/lib/v3/understudy/a11y/snapshot/index.js';
1
4
  import { incrementMetric } from '../runtime-state.js';
2
5
  import { stagehandRuntimeResolution } from '../runtime-resolution.js';
3
6
  import { withStagehand } from '../stagehand-runtime.js';
7
+ import { sanitizeExtractSnapshot } from './extract-snapshot-sanitizer.js';
4
8
  export async function executeStagehandExtract(args) {
5
9
  const { session, instruction, schema, page, selector, degradationReason } = args;
6
10
  const data = await withStagehand(session, async (stagehand) => {
7
11
  incrementMetric(session, 'stagehandCalls');
8
- return stagehand.extract(instruction, schema, {
9
- page,
10
- selector,
12
+ const internalStagehand = stagehand;
13
+ const resolvePage = internalStagehand.resolvePage;
14
+ if (typeof resolvePage !== 'function') {
15
+ if (typeof internalStagehand.extract !== 'function') {
16
+ throw new Error('Stagehand runtime does not expose resolvePage() for sanitized extract');
17
+ }
18
+ return internalStagehand.extract(instruction, schema, {
19
+ page,
20
+ selector,
21
+ });
22
+ }
23
+ const extractPage = await resolvePage.call(internalStagehand, page);
24
+ const focusSelector = selector?.replace(/^xpath=/i, '') ?? '';
25
+ const snapshot = await captureHybridSnapshot(extractPage, {
26
+ experimental: internalStagehand.experimental ?? false,
27
+ focusSelector,
11
28
  });
29
+ // Deferred decision: budget-aware narrowing stays separate from this change.
30
+ const sanitizedTree = sanitizeExtractSnapshot(snapshot.combinedTree);
31
+ const extractionResponse = await runExtract({
32
+ instruction,
33
+ domElements: sanitizedTree,
34
+ schema: schema,
35
+ llmClient: internalStagehand.llmClient,
36
+ userProvidedInstructions: internalStagehand.opts?.systemPrompt ?? '',
37
+ logger: v3Logger,
38
+ logInferenceToFile: internalStagehand.logInferenceToFile ?? false,
39
+ });
40
+ const { metadata: _metadata, prompt_tokens: _promptTokens, completion_tokens: _completionTokens, reasoning_tokens: _reasoningTokens, cached_input_tokens: _cachedInputTokens, inference_time_ms: _inferenceTimeMs, ...result } = extractionResponse;
41
+ return result;
12
42
  });
13
43
  return {
14
44
  resolvedBy: 'stagehand-extract',
@@ -1 +1 @@
1
- {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA2JnD,wBAAsB,OAAO,CAC3B,OAAO,EAAE,aAAa,EACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAgKf"}
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAyKnD,wBAAsB,OAAO,CAC3B,OAAO,EAAE,aAAa,EACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAgLf"}
@@ -2,6 +2,7 @@
2
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 { AgentpayStructuredOutputTruncatedError } from '../agentpay-stagehand-llm.js';
5
6
  import { saveSession } from '../session.js';
6
7
  import { getSurface, getTarget, markSurfaceLifecycle, markTargetLifecycle, setCurrentPage, } from '../runtime-state.js';
7
8
  import { outputContractFailure, outputJSON } from '../output.js';
@@ -120,6 +121,18 @@ function canUseTargetAsExtractScope(target) {
120
121
  }
121
122
  return Boolean(target.surfaceRef) || scopeLikeKinds.has(kind) || scopeLikeKinds.has(role);
122
123
  }
124
+ function buildTruncationReason(error) {
125
+ const details = [
126
+ error.provider ? `provider=${error.provider}` : null,
127
+ error.model ? `model=${error.model}` : null,
128
+ error.finishReason ? `finish_reason=${error.finishReason}` : null,
129
+ Number.isFinite(error.completionTokens) ? `completion_tokens=${error.completionTokens}` : null,
130
+ Number.isFinite(error.maxOutputTokens) ? `max_output_tokens=${error.maxOutputTokens}` : null,
131
+ ].filter((value) => Boolean(value));
132
+ return details.length > 0
133
+ ? `Structured output was truncated by the LLM provider (${details.join(', ')}).`
134
+ : 'Structured output was truncated by the LLM provider.';
135
+ }
123
136
  export async function extract(session, schemaJson, scopeRef) {
124
137
  let schemaDescriptor;
125
138
  try {
@@ -247,6 +260,22 @@ export async function extract(session, schemaJson, scopeRef) {
247
260
  }
248
261
  saveSession(session);
249
262
  }
263
+ if (!staleScope && err instanceof AgentpayStructuredOutputTruncatedError) {
264
+ outputContractFailure({
265
+ error: 'extract_output_truncated',
266
+ outcomeType: 'blocked',
267
+ message: 'Extraction failed because the provider truncated structured output.',
268
+ reason: buildTruncationReason(err),
269
+ scopeRef,
270
+ pageRef,
271
+ staleScope: false,
272
+ provider: err.provider,
273
+ model: err.model,
274
+ finishReason: err.finishReason,
275
+ maxOutputTokens: err.maxOutputTokens,
276
+ completionTokens: err.completionTokens,
277
+ });
278
+ }
250
279
  failureMessage = `Extract failed: ${err instanceof Error ? err.message : String(err)}`;
251
280
  }
252
281
  finally {
@@ -66,13 +66,6 @@ async function launchManaged(url, profileName, headless, compact) {
66
66
  url,
67
67
  cdpPort: CDP_PORT,
68
68
  windowSize: compact ? COMPACT_WINDOW : undefined,
69
- captchaSolver: gateway
70
- ? {
71
- apiKey: gateway.apiKey,
72
- apiUrl: gateway.apiUrl,
73
- autoSolve: config.defaults?.captchaAutoSolve !== false,
74
- }
75
- : undefined,
76
69
  });
77
70
  }
78
71
  catch (err) {
@@ -1,5 +1,5 @@
1
1
  import type { SurfaceDescriptor, TargetDescriptor, TargetValidationEvidence } from '../runtime-state.js';
2
- import type { FillableFormGuidanceHint, PersistedFillableForm, ProtectedBindingValueHint } from '../secrets/types.js';
2
+ import type { 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';
@@ -51,8 +51,6 @@ export declare function compactFillableForms(forms: ReadonlyArray<PersistedFilla
51
51
  fillRef: string;
52
52
  scopeRef?: string;
53
53
  purpose: string;
54
- recommendedTiming?: 'late';
55
- guidance?: FillableFormGuidanceHint;
56
54
  fields: Array<{
57
55
  fieldKey: string;
58
56
  targetRef: string;
@@ -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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"}