@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.
Files changed (191) hide show
  1. package/README.md +36 -8
  2. package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
  3. package/dist/agentpay-stagehand-llm.js +5 -1
  4. package/dist/commands/act.d.ts +6 -2
  5. package/dist/commands/act.d.ts.map +1 -1
  6. package/dist/commands/act.js +840 -55
  7. package/dist/commands/act.test-harness.d.ts +19 -0
  8. package/dist/commands/act.test-harness.d.ts.map +1 -0
  9. package/dist/commands/act.test-harness.js +245 -0
  10. package/dist/commands/action-acceptance.d.ts +90 -0
  11. package/dist/commands/action-acceptance.d.ts.map +1 -0
  12. package/dist/commands/action-acceptance.js +1411 -0
  13. package/dist/commands/action-artifacts.d.ts +33 -0
  14. package/dist/commands/action-artifacts.d.ts.map +1 -0
  15. package/dist/commands/action-artifacts.js +104 -0
  16. package/dist/commands/action-execution-guards.d.ts +5 -0
  17. package/dist/commands/action-execution-guards.d.ts.map +1 -0
  18. package/dist/commands/action-execution-guards.js +3 -0
  19. package/dist/commands/action-executor-helpers.d.ts +21 -0
  20. package/dist/commands/action-executor-helpers.d.ts.map +1 -0
  21. package/dist/commands/action-executor-helpers.js +242 -0
  22. package/dist/commands/action-executor.d.ts +12 -0
  23. package/dist/commands/action-executor.d.ts.map +1 -0
  24. package/dist/commands/action-executor.js +45 -0
  25. package/dist/commands/action-fallbacks.d.ts +6 -0
  26. package/dist/commands/action-fallbacks.d.ts.map +1 -0
  27. package/dist/commands/action-fallbacks.js +43 -0
  28. package/dist/commands/action-value-projection.d.ts +32 -0
  29. package/dist/commands/action-value-projection.d.ts.map +1 -0
  30. package/dist/commands/action-value-projection.js +151 -0
  31. package/dist/commands/browse-actions.d.ts +4 -0
  32. package/dist/commands/browse-actions.d.ts.map +1 -0
  33. package/dist/commands/browse-actions.js +4 -0
  34. package/dist/commands/captcha-solve.d.ts.map +1 -1
  35. package/dist/commands/captcha-solve.js +13 -3
  36. package/dist/commands/click-action-executor.d.ts +10 -0
  37. package/dist/commands/click-action-executor.d.ts.map +1 -0
  38. package/dist/commands/click-action-executor.js +68 -0
  39. package/dist/commands/create-intent.d.ts +6 -0
  40. package/dist/commands/create-intent.d.ts.map +1 -0
  41. package/dist/commands/create-intent.js +75 -0
  42. package/dist/commands/datepicker-action-executor.d.ts +12 -0
  43. package/dist/commands/datepicker-action-executor.d.ts.map +1 -0
  44. package/dist/commands/datepicker-action-executor.js +218 -0
  45. package/dist/commands/descriptor-validation.d.ts +27 -0
  46. package/dist/commands/descriptor-validation.d.ts.map +1 -0
  47. package/dist/commands/descriptor-validation.js +333 -0
  48. package/dist/commands/extract-scope-resolution.d.ts +20 -0
  49. package/dist/commands/extract-scope-resolution.d.ts.map +1 -0
  50. package/dist/commands/extract-scope-resolution.js +100 -0
  51. package/dist/commands/extract-stagehand-executor.d.ts +17 -0
  52. package/dist/commands/extract-stagehand-executor.d.ts.map +1 -0
  53. package/dist/commands/extract-stagehand-executor.js +18 -0
  54. package/dist/commands/extract.d.ts +3 -2
  55. package/dist/commands/extract.d.ts.map +1 -1
  56. package/dist/commands/extract.js +256 -39
  57. package/dist/commands/fill-secret.d.ts +7 -0
  58. package/dist/commands/fill-secret.d.ts.map +1 -0
  59. package/dist/commands/fill-secret.js +371 -0
  60. package/dist/commands/get-secrets-catalog.d.ts +6 -0
  61. package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
  62. package/dist/commands/get-secrets-catalog.js +23 -0
  63. package/dist/commands/launch.d.ts.map +1 -1
  64. package/dist/commands/launch.js +41 -7
  65. package/dist/commands/navigate.d.ts +2 -1
  66. package/dist/commands/navigate.d.ts.map +1 -1
  67. package/dist/commands/navigate.js +49 -12
  68. package/dist/commands/observe-inventory.d.ts +109 -0
  69. package/dist/commands/observe-inventory.d.ts.map +1 -0
  70. package/dist/commands/observe-inventory.js +2837 -0
  71. package/dist/commands/observe-persistence.d.ts +14 -0
  72. package/dist/commands/observe-persistence.d.ts.map +1 -0
  73. package/dist/commands/observe-persistence.js +170 -0
  74. package/dist/commands/observe-projection.d.ts +84 -0
  75. package/dist/commands/observe-projection.d.ts.map +1 -0
  76. package/dist/commands/observe-projection.js +140 -0
  77. package/dist/commands/observe-protected.d.ts +5 -0
  78. package/dist/commands/observe-protected.d.ts.map +1 -0
  79. package/dist/commands/observe-protected.js +18 -0
  80. package/dist/commands/observe-semantics.d.ts +10 -0
  81. package/dist/commands/observe-semantics.d.ts.map +1 -0
  82. package/dist/commands/observe-semantics.js +338 -0
  83. package/dist/commands/observe-stagehand.d.ts +48 -0
  84. package/dist/commands/observe-stagehand.d.ts.map +1 -0
  85. package/dist/commands/observe-stagehand.js +105 -0
  86. package/dist/commands/observe-surfaces.d.ts +9 -0
  87. package/dist/commands/observe-surfaces.d.ts.map +1 -0
  88. package/dist/commands/observe-surfaces.js +195 -0
  89. package/dist/commands/observe.d.ts +47 -1
  90. package/dist/commands/observe.d.ts.map +1 -1
  91. package/dist/commands/observe.js +173 -20
  92. package/dist/commands/observe.test-harness.d.ts +67 -0
  93. package/dist/commands/observe.test-harness.d.ts.map +1 -0
  94. package/dist/commands/observe.test-harness.js +107 -0
  95. package/dist/commands/poll-intent.d.ts +6 -0
  96. package/dist/commands/poll-intent.d.ts.map +1 -0
  97. package/dist/commands/poll-intent.js +57 -0
  98. package/dist/commands/screenshot.d.ts +2 -1
  99. package/dist/commands/screenshot.d.ts.map +1 -1
  100. package/dist/commands/screenshot.js +44 -12
  101. package/dist/commands/select-action-executor.d.ts +10 -0
  102. package/dist/commands/select-action-executor.d.ts.map +1 -0
  103. package/dist/commands/select-action-executor.js +91 -0
  104. package/dist/commands/semantic-observe.d.ts +24 -0
  105. package/dist/commands/semantic-observe.d.ts.map +1 -0
  106. package/dist/commands/semantic-observe.js +344 -0
  107. package/dist/commands/status.d.ts.map +1 -1
  108. package/dist/commands/status.js +75 -2
  109. package/dist/commands/structured-grid-action-executor.d.ts +3 -0
  110. package/dist/commands/structured-grid-action-executor.d.ts.map +1 -0
  111. package/dist/commands/structured-grid-action-executor.js +4 -0
  112. package/dist/commands/target-resolution.d.ts +4 -0
  113. package/dist/commands/target-resolution.d.ts.map +1 -0
  114. package/dist/commands/target-resolution.js +33 -0
  115. package/dist/commands/text-input-action-executor.d.ts +5 -0
  116. package/dist/commands/text-input-action-executor.d.ts.map +1 -0
  117. package/dist/commands/text-input-action-executor.js +116 -0
  118. package/dist/commands/user-actionable.d.ts +4 -0
  119. package/dist/commands/user-actionable.d.ts.map +1 -0
  120. package/dist/commands/user-actionable.js +95 -0
  121. package/dist/control-semantics.d.ts +29 -0
  122. package/dist/control-semantics.d.ts.map +1 -0
  123. package/dist/control-semantics.js +299 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +95 -32
  126. package/dist/output.d.ts +14 -2
  127. package/dist/output.d.ts.map +1 -1
  128. package/dist/output.js +17 -29
  129. package/dist/playwright-runtime.d.ts +35 -0
  130. package/dist/playwright-runtime.d.ts.map +1 -0
  131. package/dist/playwright-runtime.js +224 -0
  132. package/dist/runtime-resolution.d.ts +9 -0
  133. package/dist/runtime-resolution.d.ts.map +1 -0
  134. package/dist/runtime-resolution.js +19 -0
  135. package/dist/runtime-state.d.ts +217 -0
  136. package/dist/runtime-state.d.ts.map +1 -0
  137. package/dist/runtime-state.js +629 -0
  138. package/dist/secrets/backend.d.ts +32 -0
  139. package/dist/secrets/backend.d.ts.map +1 -0
  140. package/dist/secrets/backend.js +169 -0
  141. package/dist/secrets/catalog-applicability.d.ts +5 -0
  142. package/dist/secrets/catalog-applicability.d.ts.map +1 -0
  143. package/dist/secrets/catalog-applicability.js +59 -0
  144. package/dist/secrets/catalog-sync.d.ts +14 -0
  145. package/dist/secrets/catalog-sync.d.ts.map +1 -0
  146. package/dist/secrets/catalog-sync.js +35 -0
  147. package/dist/secrets/field-policy.d.ts +3 -0
  148. package/dist/secrets/field-policy.d.ts.map +1 -0
  149. package/dist/secrets/field-policy.js +3 -0
  150. package/dist/secrets/fill-ordering.d.ts +11 -0
  151. package/dist/secrets/fill-ordering.d.ts.map +1 -0
  152. package/dist/secrets/fill-ordering.js +44 -0
  153. package/dist/secrets/form-matcher.d.ts +60 -0
  154. package/dist/secrets/form-matcher.d.ts.map +1 -0
  155. package/dist/secrets/form-matcher.js +596 -0
  156. package/dist/secrets/intent-output.d.ts +11 -0
  157. package/dist/secrets/intent-output.d.ts.map +1 -0
  158. package/dist/secrets/intent-output.js +64 -0
  159. package/dist/secrets/mock-agentpay-backend.d.ts +13 -0
  160. package/dist/secrets/mock-agentpay-backend.d.ts.map +1 -0
  161. package/dist/secrets/mock-agentpay-backend.js +87 -0
  162. package/dist/secrets/mock-agentpay-cabinet.d.ts +43 -0
  163. package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -0
  164. package/dist/secrets/mock-agentpay-cabinet.js +195 -0
  165. package/dist/secrets/protected-artifact-guard.d.ts +25 -0
  166. package/dist/secrets/protected-artifact-guard.d.ts.map +1 -0
  167. package/dist/secrets/protected-artifact-guard.js +26 -0
  168. package/dist/secrets/protected-bindings.d.ts +10 -0
  169. package/dist/secrets/protected-bindings.d.ts.map +1 -0
  170. package/dist/secrets/protected-bindings.js +17 -0
  171. package/dist/secrets/protected-field-values.d.ts +13 -0
  172. package/dist/secrets/protected-field-values.d.ts.map +1 -0
  173. package/dist/secrets/protected-field-values.js +100 -0
  174. package/dist/secrets/protected-fill.d.ts +47 -0
  175. package/dist/secrets/protected-fill.d.ts.map +1 -0
  176. package/dist/secrets/protected-fill.js +512 -0
  177. package/dist/secrets/types.d.ts +84 -0
  178. package/dist/secrets/types.d.ts.map +1 -0
  179. package/dist/secrets/types.js +27 -0
  180. package/dist/session.d.ts +22 -0
  181. package/dist/session.d.ts.map +1 -1
  182. package/dist/session.js +74 -2
  183. package/dist/solver/browser-launcher.d.ts.map +1 -1
  184. package/dist/solver/browser-launcher.js +6 -3
  185. package/dist/stagehand-runtime.d.ts +4 -0
  186. package/dist/stagehand-runtime.d.ts.map +1 -0
  187. package/dist/stagehand-runtime.js +10 -0
  188. package/dist/stagehand.d.ts +0 -5
  189. package/dist/stagehand.d.ts.map +1 -1
  190. package/dist/stagehand.js +0 -6
  191. package/package.json +5 -2
@@ -0,0 +1,195 @@
1
+ import { locatorCandidateKey } from '../runtime-state.js';
2
+ const HIGH_SIGNAL_SCOPE_KINDS = new Set([
3
+ 'dialog',
4
+ 'listbox',
5
+ 'menu',
6
+ 'grid',
7
+ 'tabpanel',
8
+ 'popover',
9
+ 'dropdown',
10
+ 'datepicker',
11
+ ]);
12
+ export function selectScopesForOutput(scopes, targets, preferredScopeRefs) {
13
+ if (scopes.length === 0) {
14
+ return [];
15
+ }
16
+ const linkedScopeRefs = new Set(targets
17
+ .slice(0, 20)
18
+ .map((target) => target.surfaceRef)
19
+ .filter((value) => typeof value === 'string' && value.length > 0));
20
+ const scored = scopes
21
+ .map((scope) => {
22
+ const scopeTargets = targets.filter((target) => target.surfaceRef === scope.ref);
23
+ const kind = (scope.kind ?? '').toLowerCase();
24
+ const overlayLike = HIGH_SIGNAL_SCOPE_KINDS.has(kind);
25
+ const linkedCount = scopeTargets.length;
26
+ const interactionRich = scopeTargets.some((target) => target.allowedActions.includes('fill') ||
27
+ target.allowedActions.includes('select') ||
28
+ target.acceptancePolicy === 'selection' ||
29
+ target.acceptancePolicy === 'date-selection');
30
+ const directlyLinked = linkedScopeRefs.has(scope.ref);
31
+ const explicitlyPreferred = preferredScopeRefs?.has(scope.ref) === true;
32
+ let score = 0;
33
+ if (explicitlyPreferred)
34
+ score += 160;
35
+ if (directlyLinked)
36
+ score += 100;
37
+ if (overlayLike)
38
+ score += 60;
39
+ if (interactionRich)
40
+ score += 30;
41
+ score += Math.min(linkedCount, 6) * 5;
42
+ return { scope, score };
43
+ })
44
+ .filter(({ score }) => score > 0)
45
+ .sort((left, right) => right.score - left.score || left.scope.ref.localeCompare(right.scope.ref));
46
+ if (scored.length > 0) {
47
+ return scored.slice(0, 12).map(({ scope }) => scope);
48
+ }
49
+ return scopes
50
+ .filter((scope) => HIGH_SIGNAL_SCOPE_KINDS.has((scope.kind ?? '').toLowerCase()))
51
+ .slice(0, 8);
52
+ }
53
+ export function buildSurfaceRef(target) {
54
+ if (!target.surfaceKind && !target.surfaceSelector && !target.surfaceLabel) {
55
+ return undefined;
56
+ }
57
+ const frameKey = target.framePath?.join('>') ?? 'top';
58
+ return [
59
+ target.pageSignature ?? 'unknown-page',
60
+ frameKey,
61
+ target.surfaceKind ?? 'surface',
62
+ target.surfaceSelector ?? '',
63
+ target.surfaceLabel ?? '',
64
+ ].join('|');
65
+ }
66
+ export function surfaceReplacementKey(surface) {
67
+ const pageKey = surface.pageSignature ?? surface.pageRef;
68
+ const frameKey = surface.framePath?.join('>') ?? 'top';
69
+ const kindKey = (surface.kind ?? 'surface').toLowerCase();
70
+ const labelKey = (surface.label ?? '').trim().toLowerCase();
71
+ return `${pageKey}|${frameKey}|${kindKey}|${labelKey}`;
72
+ }
73
+ export function summarizeContext(context) {
74
+ if (!context)
75
+ return undefined;
76
+ const parts = [];
77
+ if (context.item?.label) {
78
+ parts.push(context.item.label);
79
+ }
80
+ else if (context.item?.kind) {
81
+ parts.push(context.item.kind);
82
+ }
83
+ if (context.group?.label) {
84
+ parts.push(context.group.label);
85
+ }
86
+ else if (context.group?.kind) {
87
+ parts.push(context.group.kind);
88
+ }
89
+ if (parts.length === 0 && context.container?.label) {
90
+ parts.push(context.container.label);
91
+ }
92
+ else if (parts.length === 0 && context.container?.kind) {
93
+ parts.push(context.container.kind);
94
+ }
95
+ if (context.landmark?.label &&
96
+ context.landmark.label !== context.container?.label &&
97
+ context.landmark.label !== context.group?.label) {
98
+ parts.push(context.landmark.label);
99
+ }
100
+ else if (context.landmark?.kind &&
101
+ context.landmark.kind !== context.container?.kind &&
102
+ context.landmark.kind !== context.group?.kind &&
103
+ !context.landmark?.label) {
104
+ parts.push(context.landmark.kind);
105
+ }
106
+ if (parts.length === 0 && context.hintText) {
107
+ parts.push(context.hintText);
108
+ }
109
+ if (parts.length === 0)
110
+ return undefined;
111
+ return parts.join(' / ');
112
+ }
113
+ export function pushUniqueLocatorCandidate(acc, candidate) {
114
+ if (!candidate)
115
+ return;
116
+ const key = locatorCandidateKey(candidate);
117
+ if (acc.some((existing) => locatorCandidateKey(existing) === key)) {
118
+ return;
119
+ }
120
+ acc.push(candidate);
121
+ }
122
+ function surfaceRoleFromKind(kind) {
123
+ const normalized = (kind ?? '').trim().toLowerCase();
124
+ switch (normalized) {
125
+ case 'card':
126
+ return 'article';
127
+ case 'article':
128
+ case 'dialog':
129
+ case 'listbox':
130
+ case 'menu':
131
+ case 'grid':
132
+ case 'tabpanel':
133
+ case 'group':
134
+ case 'region':
135
+ case 'listitem':
136
+ case 'row':
137
+ case 'form':
138
+ return normalized;
139
+ case 'fieldset':
140
+ return 'group';
141
+ case 'section':
142
+ return 'region';
143
+ default:
144
+ return undefined;
145
+ }
146
+ }
147
+ function collectSurfaceLocatorCandidates(target) {
148
+ const candidates = [];
149
+ const selectors = [target.surfaceSelector, ...(target.surfaceSelectors ?? [])].filter((value) => typeof value === 'string' && value.length > 0);
150
+ for (const selector of selectors) {
151
+ pushUniqueLocatorCandidate(candidates, {
152
+ strategy: selector.startsWith('xpath=') ? 'xpath' : 'css',
153
+ value: selector,
154
+ scope: 'root',
155
+ });
156
+ }
157
+ const surfaceRole = surfaceRoleFromKind(target.surfaceKind);
158
+ if (surfaceRole) {
159
+ pushUniqueLocatorCandidate(candidates, target.surfaceLabel
160
+ ? { strategy: 'role', value: surfaceRole, name: target.surfaceLabel }
161
+ : undefined);
162
+ pushUniqueLocatorCandidate(candidates, { strategy: 'role', value: surfaceRole });
163
+ }
164
+ return candidates;
165
+ }
166
+ export function collectSurfaceDescriptors(pageRef, targets) {
167
+ const descriptors = new Map();
168
+ for (const target of targets) {
169
+ const surfaceId = target.surfaceRef;
170
+ if (!surfaceId) {
171
+ continue;
172
+ }
173
+ const existing = descriptors.get(surfaceId);
174
+ const locatorCandidates = existing ? [...existing.locatorCandidates] : [];
175
+ for (const candidate of collectSurfaceLocatorCandidates(target)) {
176
+ pushUniqueLocatorCandidate(locatorCandidates, candidate);
177
+ }
178
+ descriptors.set(surfaceId, {
179
+ surfaceId,
180
+ pageRef,
181
+ framePath: existing?.framePath ?? target.framePath,
182
+ frameUrl: existing?.frameUrl ?? target.frameUrl,
183
+ kind: existing?.kind ?? target.surfaceKind ?? 'surface',
184
+ label: existing?.label && existing.label !== 'Active surface'
185
+ ? existing.label
186
+ : target.surfaceLabel ?? target.surfaceKind ?? existing?.label ?? 'Active surface',
187
+ lifecycle: 'live',
188
+ availability: { state: 'available' },
189
+ locatorCandidates,
190
+ createdAt: existing?.createdAt ?? Date.now(),
191
+ pageSignature: existing?.pageSignature ?? target.pageSignature,
192
+ });
193
+ }
194
+ return [...descriptors.values()];
195
+ }
@@ -1,5 +1,51 @@
1
1
  /**
2
2
  * browse observe ["<instruction>"] — Discover available actions on the page.
3
3
  */
4
- export declare function observe(cdpUrl: string, instruction?: string): Promise<void>;
4
+ import type { BrowseSession } from '../session.js';
5
+ import { toStagehandDescriptor } from './observe-stagehand.js';
6
+ export declare const __testDomTargetCollection: {
7
+ collectDomTargetsFromDocument: (context: {
8
+ evaluate<T>(pageFunction: string): Promise<T>;
9
+ }, options?: import("./observe-inventory.js").DomTargetCollectionOptions & {
10
+ framePath?: string[];
11
+ frameUrl?: string;
12
+ }) => Promise<import("./observe-inventory.js").DomObservedTarget[]>;
13
+ collectPageSignalsFromDocument: (context: {
14
+ evaluate<T>(pageFunction: string): Promise<T>;
15
+ }, options?: {
16
+ framePath?: string[];
17
+ frameUrl?: string;
18
+ }) => Promise<import("./observe-inventory.js").ObservedPageSignal[]>;
19
+ locatorDomSignatureScript: string;
20
+ };
21
+ export declare const __testStagehandDescriptor: {
22
+ toStagehandDescriptor: typeof toStagehandDescriptor;
23
+ normalizeStagehandSelector: typeof import("./observe-inventory.js").normalizeStagehandSelector;
24
+ readStagehandDomFacts: (locator: import("playwright-core").Locator) => Promise<{
25
+ kind?: string;
26
+ role?: string;
27
+ placeholder?: string;
28
+ inputName?: string;
29
+ inputType?: string;
30
+ autocomplete?: string;
31
+ value?: string;
32
+ text?: string;
33
+ currentValue?: string;
34
+ states?: Record<string, string | boolean | number>;
35
+ } | null>;
36
+ readStagehandDomFactsInBrowser: (element: Element) => {
37
+ kind?: string;
38
+ role?: string;
39
+ placeholder?: string;
40
+ inputName?: string;
41
+ inputType?: string;
42
+ autocomplete?: string;
43
+ value?: string;
44
+ text?: string;
45
+ currentValue?: string;
46
+ states?: Record<string, string | boolean | number>;
47
+ } | null;
48
+ stagehandDomFactsScript: string;
49
+ };
50
+ export declare function observe(session: BrowseSession, instruction?: string): Promise<void>;
5
51
  //# sourceMappingURL=observe.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/commands/observe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCjF"}
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;AA+CnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAU/D,eAAO,MAAM,yBAAyB;;;;iBA0Ou0F,CAAC;gBAAwB,CAAC;;;;;iBAAq7vE,CAAC;gBAAwB,CAAC;;;CA1Ojx1E,CAAC;AACtE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGrC,CAAC;AAEF,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmOzF"}
@@ -1,37 +1,190 @@
1
1
  /**
2
2
  * browse observe ["<instruction>"] — Discover available actions on the page.
3
3
  */
4
- import { connectStagehand, getPageInfo } from '../stagehand.js';
5
- import { outputJSON, outputError } from '../output.js';
6
- export async function observe(cdpUrl, instruction) {
7
- let stagehand;
4
+ import { saveSession } from '../session.js';
5
+ import { ensureRuntimeState, incrementMetric, replaceTargetsForPage } from '../runtime-state.js';
6
+ import { connectPlaywright, disconnectPlaywright, resolvePageByRef, syncSessionPage, } from '../playwright-runtime.js';
7
+ import { outputContractFailure, outputJSON } from '../output.js';
8
+ import { domRuntimeResolution, stagehandRuntimeResolution } from '../runtime-resolution.js';
9
+ import { withStagehand } from '../stagehand-runtime.js';
10
+ import { normalizePageSignature } from './descriptor-validation.js';
11
+ import { collectDomTargets, collectPageSignals, __testDomTargetCollection as inventoryDomTargetCollection, __testStagehandDescriptor as inventoryStagehandDescriptor, } from './observe-inventory.js';
12
+ import { attachObservedTargetOwners, reconcileObservedTargetsForPage, persistObservedSurfacesForPage, toDomDescriptor, } from './observe-persistence.js';
13
+ import { clearProtectedFillableFormsForPage, persistProtectedFillableFormsForPage, } from './observe-protected.js';
14
+ import { annotateDomTargets, compressSemanticallyDuplicateTargets, expandRerankedFormTargets, orderBySurfaceCompetition, } from './observe-semantics.js';
15
+ import { buildExplicitScopeRefs, buildGoalObserveInventoryCandidates, compactFillableForms, compactScopes, compactSignals, compactTargets, projectPersistedTargetsForGoal, selectTargetsForGoalMatches, } from './observe-projection.js';
16
+ import { collectSurfaceDescriptors, selectScopesForOutput } from './observe-surfaces.js';
17
+ import { toStagehandDescriptor } from './observe-stagehand.js';
18
+ import { rerankDomTargetsForGoal } from './semantic-observe.js';
19
+ export const __testDomTargetCollection = inventoryDomTargetCollection;
20
+ export const __testStagehandDescriptor = {
21
+ ...inventoryStagehandDescriptor,
22
+ toStagehandDescriptor,
23
+ };
24
+ export async function observe(session, instruction) {
25
+ const runtime = ensureRuntimeState(session);
26
+ const pageRef = runtime.currentPageRef;
27
+ let domPassError = null;
28
+ let stagehandFallbackReason = null;
29
+ let browser = null;
30
+ let observedScopes = [];
31
+ if (!instruction) {
32
+ try {
33
+ browser = await connectPlaywright(session.cdpUrl);
34
+ const page = await resolvePageByRef(browser, session, pageRef);
35
+ const { url, title } = await syncSessionPage(session, pageRef, page);
36
+ const domTargets = compressSemanticallyDuplicateTargets(orderBySurfaceCompetition(annotateDomTargets(await collectDomTargets(page))));
37
+ const signals = compactSignals(await collectPageSignals(page).catch(() => []));
38
+ const persisted = persistObservedSurfacesForPage(session, pageRef, domTargets);
39
+ observedScopes = persisted.observedScopes;
40
+ const surfaceRefMap = persisted.surfaceRefMap;
41
+ if (domTargets.length > 0) {
42
+ const targets = replaceTargetsForPage(session, pageRef, domTargets.map((target) => toDomDescriptor(pageRef, target, surfaceRefMap)));
43
+ reconcileObservedTargetsForPage(session, pageRef, targets);
44
+ attachObservedTargetOwners(domTargets, targets);
45
+ const fillableForms = await persistProtectedFillableFormsForPage(session, pageRef, url, targets, new Date().toISOString());
46
+ saveSession(session);
47
+ disconnectPlaywright(browser);
48
+ browser = null;
49
+ outputJSON({
50
+ success: true,
51
+ pageRef,
52
+ resolvedBy: 'dom',
53
+ ...domRuntimeResolution(),
54
+ scopes: compactScopes(selectScopesForOutput(observedScopes, targets)),
55
+ targets: compactTargets(targets),
56
+ signals,
57
+ fillableForms: compactFillableForms(fillableForms),
58
+ metrics: session.runtime?.metrics,
59
+ message: targets.length === 0 ? 'No targets found.' : undefined,
60
+ url,
61
+ title,
62
+ });
63
+ return;
64
+ }
65
+ stagehandFallbackReason = 'deterministic-observe-empty';
66
+ }
67
+ catch (err) {
68
+ domPassError = err instanceof Error ? err.message : String(err);
69
+ stagehandFallbackReason = 'deterministic-observe-failed';
70
+ }
71
+ }
72
+ if (instruction) {
73
+ try {
74
+ if (!browser) {
75
+ browser = await connectPlaywright(session.cdpUrl);
76
+ }
77
+ const page = await resolvePageByRef(browser, session, pageRef);
78
+ const { url, title } = await syncSessionPage(session, pageRef, page);
79
+ const domTargets = compressSemanticallyDuplicateTargets(orderBySurfaceCompetition(annotateDomTargets(await collectDomTargets(page, { includeActivationAffordances: true }))));
80
+ const signals = compactSignals(await collectPageSignals(page).catch(() => []));
81
+ const surfaceInputs = collectSurfaceDescriptors(pageRef, domTargets);
82
+ if (domTargets.length > 0) {
83
+ const rerankedCandidates = await rerankDomTargetsForGoal(instruction, buildGoalObserveInventoryCandidates(domTargets, surfaceInputs));
84
+ const { targets: goalMatchedTargets, selectedSurfaceIds } = selectTargetsForGoalMatches(domTargets, rerankedCandidates);
85
+ const selectedTargets = expandRerankedFormTargets(domTargets, goalMatchedTargets);
86
+ if (selectedTargets.length > 0 || selectedSurfaceIds.size > 0) {
87
+ const persisted = persistObservedSurfacesForPage(session, pageRef, domTargets, {
88
+ allSurfaceInputs: surfaceInputs,
89
+ explicitSurfaceIds: selectedSurfaceIds,
90
+ });
91
+ observedScopes = persisted.observedScopes;
92
+ const surfaceRefMap = persisted.surfaceRefMap;
93
+ const targets = replaceTargetsForPage(session, pageRef, domTargets.map((target) => toDomDescriptor(pageRef, target, surfaceRefMap)));
94
+ reconcileObservedTargetsForPage(session, pageRef, targets);
95
+ const explicitScopeRefs = buildExplicitScopeRefs(selectedSurfaceIds, surfaceRefMap);
96
+ attachObservedTargetOwners(domTargets, targets);
97
+ const fillableForms = await persistProtectedFillableFormsForPage(session, pageRef, url, targets, new Date().toISOString());
98
+ const projectedTargets = projectPersistedTargetsForGoal(domTargets, targets, selectedTargets);
99
+ saveSession(session);
100
+ disconnectPlaywright(browser);
101
+ browser = null;
102
+ outputJSON({
103
+ success: true,
104
+ pageRef,
105
+ resolvedBy: 'dom-rerank',
106
+ ...domRuntimeResolution(),
107
+ scopes: compactScopes(selectScopesForOutput(observedScopes, projectedTargets, explicitScopeRefs)),
108
+ targets: compactTargets(projectedTargets),
109
+ signals,
110
+ fillableForms: compactFillableForms(fillableForms),
111
+ metrics: session.runtime?.metrics,
112
+ url,
113
+ title,
114
+ });
115
+ return;
116
+ }
117
+ stagehandFallbackReason = 'dom-rerank-empty';
118
+ }
119
+ else {
120
+ stagehandFallbackReason = 'deterministic-observe-empty';
121
+ }
122
+ }
123
+ catch (err) {
124
+ domPassError = err instanceof Error ? err.message : String(err);
125
+ stagehandFallbackReason = 'deterministic-observe-failed';
126
+ }
127
+ }
8
128
  try {
9
- stagehand = await connectStagehand(cdpUrl);
129
+ if (!browser) {
130
+ browser = await connectPlaywright(session.cdpUrl);
131
+ }
10
132
  }
11
133
  catch (err) {
12
- outputError(`Failed to connect to browser: ${err instanceof Error ? err.message : String(err)}`);
134
+ const domFailure = domPassError && domPassError.length > 0 ? `; dom observe failed: ${domPassError}` : '';
135
+ outputContractFailure({
136
+ error: 'browser_connection_failed',
137
+ outcomeType: 'blocked',
138
+ message: 'Observe could not start because AgentBrowse failed to connect to the browser.',
139
+ reason: `${err instanceof Error ? err.message : String(err)}${domFailure}`,
140
+ pageRef,
141
+ });
13
142
  }
14
143
  try {
15
- const actions = instruction
16
- ? await stagehand.observe(instruction)
17
- : await stagehand.observe();
18
- const { url, title } = await getPageInfo(stagehand);
19
- await stagehand.close();
144
+ const page = await resolvePageByRef(browser, session, pageRef);
145
+ const { url, title } = await syncSessionPage(session, pageRef, page);
146
+ const signals = compactSignals(await collectPageSignals(page).catch(() => []));
147
+ const actions = await withStagehand(session, async (stagehand) => {
148
+ incrementMetric(session, 'stagehandCalls');
149
+ return instruction
150
+ ? (await stagehand.observe(instruction, { page }))
151
+ : (await stagehand.observe({ page }));
152
+ });
153
+ const targets = replaceTargetsForPage(session, pageRef, await Promise.all(actions.map((action) => toStagehandDescriptor(pageRef, action, page, normalizePageSignature(url)))));
154
+ const fillableForms = clearProtectedFillableFormsForPage(session, pageRef);
155
+ saveSession(session);
20
156
  outputJSON({
21
157
  success: true,
22
- message: actions.length === 0 ? 'No actions found by Stagehand observe.' : undefined,
23
- actions: actions.map((a) => ({
24
- description: a.description,
25
- selector: a.selector,
26
- method: a.method,
27
- arguments: a.arguments,
28
- })),
158
+ pageRef,
159
+ resolvedBy: 'stagehand-observe',
160
+ ...stagehandRuntimeResolution(stagehandFallbackReason ?? 'deterministic-observe-failed'),
161
+ deterministicObserveError: domPassError ?? undefined,
162
+ scopes: compactScopes(selectScopesForOutput(observedScopes, targets)),
163
+ targets: compactTargets(targets),
164
+ signals,
165
+ fillableForms: compactFillableForms(fillableForms),
166
+ metrics: session.runtime?.metrics,
167
+ message: targets.length === 0 ? 'No targets found.' : undefined,
29
168
  url,
30
169
  title,
31
170
  });
32
171
  }
33
172
  catch (err) {
34
- await stagehand.close();
35
- outputError(`Observe failed: ${err instanceof Error ? err.message : String(err)}`);
173
+ const stagehandError = err instanceof Error ? err.message : String(err);
174
+ const details = domPassError
175
+ ? `${stagehandError} (deterministic observe failed earlier: ${domPassError})`
176
+ : stagehandError;
177
+ outputContractFailure({
178
+ error: 'observe_failed',
179
+ outcomeType: 'blocked',
180
+ message: 'Observe failed.',
181
+ reason: details,
182
+ pageRef,
183
+ });
184
+ }
185
+ finally {
186
+ if (browser) {
187
+ disconnectPlaywright(browser);
188
+ }
36
189
  }
37
190
  }
@@ -0,0 +1,67 @@
1
+ import { vi } from 'vitest';
2
+ import type { BrowseSession } from '../session.js';
3
+ type ViMock = ReturnType<typeof vi.fn>;
4
+ export declare const connectOverCDPMock: ViMock;
5
+ export declare const connectStagehandMock: ViMock;
6
+ export declare const outputContractFailureMock: ViMock;
7
+ export declare const outputErrorMock: ViMock;
8
+ export declare const outputFailureMock: ViMock;
9
+ export declare const outputJSONMock: ViMock;
10
+ export declare const rerankDomTargetsForGoalMock: ViMock;
11
+ export declare const saveSessionMock: ViMock;
12
+ export declare const observe: typeof import("./observe.js").observe, __testDomTargetCollection: {
13
+ collectDomTargetsFromDocument: (context: {
14
+ evaluate<T>(pageFunction: string): Promise<T>;
15
+ }, options?: import("./observe-inventory.js").DomTargetCollectionOptions & {
16
+ framePath?: string[];
17
+ frameUrl?: string;
18
+ }) => Promise<import("./observe-inventory.js").DomObservedTarget[]>;
19
+ collectPageSignalsFromDocument: (context: {
20
+ evaluate<T>(pageFunction: string): Promise<T>;
21
+ }, options?: {
22
+ framePath?: string[];
23
+ frameUrl?: string;
24
+ }) => Promise<import("./observe-inventory.js").ObservedPageSignal[]>;
25
+ locatorDomSignatureScript: string;
26
+ }, __testStagehandDescriptor: {
27
+ toStagehandDescriptor: typeof import("./observe-stagehand.js").toStagehandDescriptor;
28
+ normalizeStagehandSelector: typeof import("./observe-inventory.js").normalizeStagehandSelector;
29
+ readStagehandDomFacts: (locator: import("playwright-core").Locator) => Promise<{
30
+ kind?: string;
31
+ role?: string;
32
+ placeholder?: string;
33
+ inputName?: string;
34
+ inputType?: string;
35
+ autocomplete?: string;
36
+ value?: string;
37
+ text?: string;
38
+ currentValue?: string;
39
+ states?: Record<string, string | boolean | number>;
40
+ } | null>;
41
+ readStagehandDomFactsInBrowser: (element: Element) => {
42
+ kind?: string;
43
+ role?: string;
44
+ placeholder?: string;
45
+ inputName?: string;
46
+ inputType?: string;
47
+ autocomplete?: string;
48
+ value?: string;
49
+ text?: string;
50
+ currentValue?: string;
51
+ states?: Record<string, string | boolean | number>;
52
+ } | null;
53
+ stagehandDomFactsScript: string;
54
+ };
55
+ export declare const __testDescriptorValidation: {
56
+ readLocatorDomSignatureInBrowser: (element: Element) => string | null;
57
+ locatorDomSignatureScript: string;
58
+ locatorBindingSnapshotScript: string;
59
+ isCompatibleMutableFieldBinding: typeof import("./descriptor-validation.js").isCompatibleMutableFieldBinding;
60
+ };
61
+ export declare function makeSession(): BrowseSession;
62
+ export declare function withStagehandLocator<T extends Record<string, unknown>>(page: T, domSignature?: string): T & {
63
+ locator: ReturnType<typeof vi.fn>;
64
+ };
65
+ export declare function installObserveTestHooks(): void;
66
+ export {};
67
+ //# sourceMappingURL=observe.test-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe.test-harness.d.ts","sourceRoot":"","sources":["../../src/commands/observe.test-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAmBvC,eAAO,MAAM,kBAAkB,EAAE,MAAiC,CAAC;AACnE,eAAO,MAAM,oBAAoB,EAAE,MAAmC,CAAC;AACvE,eAAO,MAAM,yBAAyB,EAAE,MAAwC,CAAC;AACjF,eAAO,MAAM,eAAe,EAAE,MAA8B,CAAC;AAC7D,eAAO,MAAM,iBAAiB,EAAE,MAAgC,CAAC;AACjE,eAAO,MAAM,cAAc,EAAE,MAA6B,CAAC;AAC3D,eAAO,MAAM,2BAA2B,EAAE,MAA0C,CAAC;AACrF,eAAO,MAAM,eAAe,EAAE,MAA8B,CAAC;AA+B7D,eAAO,MAAQ,OAAO,yCAAE,yBAAyB;;;;iBAoEo/R,CAAC;gBAAwB,CAAC;;;;;iBAAq7vE,CAAC;gBAAwB,CAAC;;;GApE39hF,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAE3E,CAAC;AACF,eAAO,MAAQ,0BAA0B;;;;;CAA+C,CAAC;AAMzF,wBAAgB,WAAW,IAAI,aAAa,CAW3C;AAYD,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpE,IAAI,EAAE,CAAC,EACP,YAAY,SAAkC,GAC7C,CAAC,GAAG;IAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;CAAE,CAM3C;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAwB9C"}
@@ -0,0 +1,107 @@
1
+ import { afterEach, beforeEach, vi } from 'vitest';
2
+ import { registerPage } from '../runtime-state.js';
3
+ const mocks = vi.hoisted(() => ({
4
+ connectOverCDPMock: vi.fn(),
5
+ connectStagehandMock: vi.fn(),
6
+ outputContractFailureMock: vi.fn((payload) => {
7
+ throw new Error(`outputContractFailure:${JSON.stringify(payload)}`);
8
+ }),
9
+ outputErrorMock: vi.fn((message) => {
10
+ throw new Error(message);
11
+ }),
12
+ outputFailureMock: vi.fn((payload) => {
13
+ throw new Error(`outputFailure:${JSON.stringify(payload)}`);
14
+ }),
15
+ outputJSONMock: vi.fn(),
16
+ rerankDomTargetsForGoalMock: vi.fn(async (..._args) => []),
17
+ saveSessionMock: vi.fn(),
18
+ }));
19
+ export const connectOverCDPMock = mocks.connectOverCDPMock;
20
+ export const connectStagehandMock = mocks.connectStagehandMock;
21
+ export const outputContractFailureMock = mocks.outputContractFailureMock;
22
+ export const outputErrorMock = mocks.outputErrorMock;
23
+ export const outputFailureMock = mocks.outputFailureMock;
24
+ export const outputJSONMock = mocks.outputJSONMock;
25
+ export const rerankDomTargetsForGoalMock = mocks.rerankDomTargetsForGoalMock;
26
+ export const saveSessionMock = mocks.saveSessionMock;
27
+ vi.mock('playwright-core', () => ({
28
+ chromium: {
29
+ connectOverCDP: connectOverCDPMock,
30
+ },
31
+ }));
32
+ vi.mock('../stagehand.js', () => ({
33
+ connectStagehand: connectStagehandMock,
34
+ }));
35
+ vi.mock('../output.js', () => ({
36
+ outputContractFailure: outputContractFailureMock,
37
+ outputFailure: outputFailureMock,
38
+ outputError: outputErrorMock,
39
+ outputJSON: outputJSONMock,
40
+ }));
41
+ vi.mock('./semantic-observe.js', () => ({
42
+ rerankDomTargetsForGoal: rerankDomTargetsForGoalMock,
43
+ }));
44
+ vi.mock('../session.js', async () => {
45
+ const actual = await vi.importActual('../session.js');
46
+ return {
47
+ ...actual,
48
+ saveSession: saveSessionMock,
49
+ };
50
+ });
51
+ export const { observe, __testDomTargetCollection, __testStagehandDescriptor } = await import('./observe.js');
52
+ export const { __testDescriptorValidation } = await import('./descriptor-validation.js');
53
+ const originalFetch = globalThis.fetch;
54
+ const originalApiKey = process.env.AGENTPAY_API_KEY;
55
+ const originalApiUrl = process.env.AGENTPAY_API_URL;
56
+ export function makeSession() {
57
+ const session = {
58
+ cdpUrl: 'ws://localhost:9222/devtools/browser/test',
59
+ pid: 1,
60
+ launchedAt: new Date(0).toISOString(),
61
+ };
62
+ registerPage(session, {
63
+ pageRef: 'p0',
64
+ makeCurrent: true,
65
+ });
66
+ return session;
67
+ }
68
+ function makeStagehandLocator(domSignature = 'button|button|Observed target') {
69
+ const locator = {
70
+ evaluate: vi.fn(async () => domSignature),
71
+ first: vi.fn(),
72
+ waitFor: vi.fn(async () => { }),
73
+ };
74
+ locator.first.mockReturnValue(locator);
75
+ return locator;
76
+ }
77
+ export function withStagehandLocator(page, domSignature = 'button|button|Observed target') {
78
+ const locator = makeStagehandLocator(domSignature);
79
+ return {
80
+ ...page,
81
+ locator: vi.fn(() => locator),
82
+ };
83
+ }
84
+ export function installObserveTestHooks() {
85
+ beforeEach(() => {
86
+ connectOverCDPMock.mockReset();
87
+ connectStagehandMock.mockReset();
88
+ outputContractFailureMock.mockReset();
89
+ outputContractFailureMock.mockImplementation((payload) => {
90
+ throw new Error(`outputContractFailure:${JSON.stringify(payload)}`);
91
+ });
92
+ outputErrorMock.mockClear();
93
+ outputFailureMock.mockReset();
94
+ outputFailureMock.mockImplementation((payload) => {
95
+ throw new Error(`outputFailure:${JSON.stringify(payload)}`);
96
+ });
97
+ outputJSONMock.mockClear();
98
+ rerankDomTargetsForGoalMock.mockReset();
99
+ rerankDomTargetsForGoalMock.mockResolvedValue([]);
100
+ saveSessionMock.mockReset();
101
+ });
102
+ afterEach(() => {
103
+ globalThis.fetch = originalFetch;
104
+ process.env.AGENTPAY_API_KEY = originalApiKey;
105
+ process.env.AGENTPAY_API_URL = originalApiUrl;
106
+ });
107
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * browse poll-intent <intentId> — Poll stored-secret intent state and capture one-time delivery.
3
+ */
4
+ import type { BrowseSession } from '../session.js';
5
+ export declare function pollIntent(session: BrowseSession, intentId: string): Promise<void>;
6
+ //# sourceMappingURL=poll-intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll-intent.d.ts","sourceRoot":"","sources":["../../src/commands/poll-intent.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAKnD,wBAAsB,UAAU,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDxF"}