@mercuryo-ai/agentbrowse 0.2.61 → 0.2.63
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/CHANGELOG.md +33 -1
- package/README.md +102 -9
- package/dist/browser-session-state.d.ts +2 -11
- package/dist/browser-session-state.d.ts.map +1 -1
- package/dist/browser-session-state.js +0 -4
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +14 -5
- package/dist/commands/attach.d.ts +1 -3
- package/dist/commands/attach.d.ts.map +1 -1
- package/dist/commands/attach.js +0 -2
- package/dist/commands/browser-status.d.ts +0 -2
- package/dist/commands/browser-status.d.ts.map +1 -1
- package/dist/commands/browser-status.js +1 -7
- package/dist/commands/interaction-kernel.d.ts +1 -1
- package/dist/commands/interaction-kernel.d.ts.map +1 -1
- package/dist/commands/interaction-kernel.js +1 -1
- package/dist/commands/launch.d.ts +0 -1
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +0 -4
- package/dist/commands/observe-accessibility.d.ts.map +1 -1
- package/dist/commands/observe-accessibility.js +36 -2
- package/dist/commands/observe-inventory.d.ts +49 -7
- package/dist/commands/observe-inventory.d.ts.map +1 -1
- package/dist/commands/observe-inventory.js +807 -96
- package/dist/commands/observe-persistence.d.ts.map +1 -1
- package/dist/commands/observe-persistence.js +49 -6
- package/dist/commands/observe-projection.d.ts +6 -2
- package/dist/commands/observe-projection.d.ts.map +1 -1
- package/dist/commands/observe-projection.js +251 -27
- package/dist/commands/observe-semantics.d.ts +1 -0
- package/dist/commands/observe-semantics.d.ts.map +1 -1
- package/dist/commands/observe-semantics.js +541 -135
- package/dist/commands/observe-signals.d.ts +4 -4
- package/dist/commands/observe-signals.d.ts.map +1 -1
- package/dist/commands/observe-signals.js +2 -2
- package/dist/commands/observe-surfaces.d.ts +2 -1
- package/dist/commands/observe-surfaces.d.ts.map +1 -1
- package/dist/commands/observe-surfaces.js +143 -45
- package/dist/commands/observe.d.ts +5 -1
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +15 -11
- package/dist/commands/semantic-observe.d.ts.map +1 -1
- package/dist/commands/semantic-observe.js +43 -0
- package/dist/library.d.ts +2 -1
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +2 -1
- package/dist/match-resolve-fill.d.ts +196 -0
- package/dist/match-resolve-fill.d.ts.map +1 -0
- package/dist/match-resolve-fill.js +700 -0
- package/dist/match-resolve-fill.test-support.d.ts +34 -0
- package/dist/match-resolve-fill.test-support.d.ts.map +1 -0
- package/dist/match-resolve-fill.test-support.js +81 -0
- package/dist/runtime-protected-state.d.ts.map +1 -1
- package/dist/runtime-protected-state.js +12 -0
- package/dist/runtime-state.d.ts +6 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +6 -0
- package/dist/secrets/form-matcher.d.ts.map +1 -1
- package/dist/secrets/form-matcher.js +76 -27
- package/dist/secrets/protected-exact-value-redaction.d.ts.map +1 -1
- package/dist/secrets/protected-exact-value-redaction.js +6 -0
- package/dist/secrets/protected-fill.js +3 -3
- package/dist/session.d.ts +3 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +2 -2
- package/dist/solver/browser-launcher.d.ts.map +1 -1
- package/dist/solver/browser-launcher.js +2 -1
- package/dist/testing.d.ts +1 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +1 -0
- package/docs/README.md +28 -11
- package/docs/api-reference.md +311 -19
- package/docs/assistive-runtime.md +41 -16
- package/docs/getting-started.md +45 -1
- package/docs/integration-checklist.md +32 -3
- package/docs/match-resolve-fill.md +699 -0
- package/docs/protected-fill.md +373 -91
- package/docs/testing.md +147 -15
- package/docs/troubleshooting.md +5 -0
- package/examples/README.md +7 -0
- package/examples/match-resolve-fill.ts +107 -0
- package/package.json +4 -2
package/docs/api-reference.md
CHANGED
|
@@ -97,21 +97,211 @@ Captures a screenshot of the current page.
|
|
|
97
97
|
|
|
98
98
|
Closes the browser session.
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
### `match(subject, options)`
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
Decides which caller-supplied candidate value fits an observed target or
|
|
103
|
+
fillable form. Pure and local — does not call the network and does not
|
|
104
|
+
mutate browser state. See
|
|
105
|
+
[Match / Resolve / Fill Guide](./match-resolve-fill.md) for the full
|
|
106
|
+
mental model.
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
```ts
|
|
109
|
+
function match(
|
|
110
|
+
subject: TargetDescriptor | ProtectedFillForm,
|
|
111
|
+
options: AgentbrowseMatchOptions,
|
|
112
|
+
): Promise<AgentbrowseMatchResult>;
|
|
113
|
+
|
|
114
|
+
interface AgentbrowseMatchOptions {
|
|
115
|
+
from: AgentbrowseMatchSource;
|
|
116
|
+
host?: string;
|
|
117
|
+
protectedTargetRefs?: ReadonlySet<string>;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `resolve(plan, options)`
|
|
122
|
+
|
|
123
|
+
Turns one or many `needs_resolution` plans into ready match results
|
|
124
|
+
through a caller-supplied adapter. `ready` results pass through
|
|
125
|
+
untouched. Overloaded for single plan and batch arrays.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
function resolve(
|
|
129
|
+
plan: AgentbrowseMatchResult,
|
|
130
|
+
options: AgentbrowseResolveOptions,
|
|
131
|
+
): Promise<AgentbrowseMatchResult>;
|
|
132
|
+
|
|
133
|
+
function resolve(
|
|
134
|
+
plans: ReadonlyArray<AgentbrowseMatchResult>,
|
|
135
|
+
options: AgentbrowseResolveOptions,
|
|
136
|
+
): Promise<AgentbrowseMatchResult[]>;
|
|
137
|
+
|
|
138
|
+
interface AgentbrowseResolveOptions {
|
|
139
|
+
with: AgentbrowseMatchResolver;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `fill(session, subject, plan, options?)`
|
|
144
|
+
|
|
145
|
+
Applies a match result to the browser. Dereferences the opaque
|
|
146
|
+
value/artifact ref internally and hands off to the standard `act(...)`
|
|
147
|
+
path (single targets) or `resolver.fill(...)` (grouped protected forms).
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
function fill(
|
|
151
|
+
session: BrowserCommandSession,
|
|
152
|
+
subject: Pick<TargetDescriptor, 'ref'> | ProtectedFillForm,
|
|
153
|
+
plan: AgentbrowseMatchResult,
|
|
154
|
+
options?: AgentbrowseFillOptions,
|
|
155
|
+
): Promise<AgentbrowseFillResult>;
|
|
156
|
+
|
|
157
|
+
interface AgentbrowseFillOptions {
|
|
158
|
+
resolver?: AgentbrowseMatchResolver;
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`fill(...)` can run `resolve` inline when you pass a `resolver` for a
|
|
163
|
+
plan that still needs resolution — equivalent to the two-call form. See
|
|
164
|
+
[match-resolve-fill.md → Walk-through 3](./match-resolve-fill.md#walk-through-3--collapsing-to-one-call).
|
|
113
165
|
|
|
114
|
-
|
|
166
|
+
## Result Shape
|
|
167
|
+
|
|
168
|
+
All main commands share the same top-level pattern.
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
// success
|
|
172
|
+
{ success: true, ...commandSpecificFields }
|
|
173
|
+
|
|
174
|
+
// failure
|
|
175
|
+
{
|
|
176
|
+
success: false,
|
|
177
|
+
error: <ErrorCode>,
|
|
178
|
+
outcomeType: <OutcomeType>,
|
|
179
|
+
message: string,
|
|
180
|
+
reason: string,
|
|
181
|
+
...commandSpecificFields,
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- `error` — stable top-level code from the per-command table below.
|
|
186
|
+
Branch on this, not on `reason` or `message`.
|
|
187
|
+
- `outcomeType` — stable outcome category (e.g. `binding_stale`,
|
|
188
|
+
`blocked`). Same vocabulary per command as the `*_OUTCOME_TYPES`
|
|
189
|
+
exports.
|
|
190
|
+
- `message` — human-readable short message.
|
|
191
|
+
- `reason` — detailed reason string. Usually a lower-level error code,
|
|
192
|
+
a truncation detail, or an explanation; see the sticky-owner note
|
|
193
|
+
below for one common special case.
|
|
194
|
+
|
|
195
|
+
The root package exports stable arrays backing the `*ErrorCode` and
|
|
196
|
+
`*OutcomeType` types for every command: `ACT_ERROR_CODES`,
|
|
197
|
+
`ACT_OUTCOME_TYPES`, `ATTACH_ERROR_CODES`, `CLOSE_ERROR_CODES`,
|
|
198
|
+
`EXTRACT_ERROR_CODES`, `EXTRACT_OUTCOME_TYPES`, `LAUNCH_ERROR_CODES`,
|
|
199
|
+
`NAVIGATE_ERROR_CODES`, `OBSERVE_ERROR_CODES`, `OBSERVE_OUTCOME_TYPES`,
|
|
200
|
+
`SCREENSHOT_ERROR_CODES`, `SCREENSHOT_OUTCOME_TYPES`.
|
|
201
|
+
|
|
202
|
+
### Cross-command codes
|
|
203
|
+
|
|
204
|
+
Any command that drives an already-open browser session may surface:
|
|
205
|
+
|
|
206
|
+
| `error` | When | Action |
|
|
207
|
+
| --- | --- | --- |
|
|
208
|
+
| `browser_connection_failed` | AgentBrowse could not reach the browser. | Check `reason`. A common special value is `sticky_owner_unrecoverable` — the prior browser session is lost; launch or attach a fresh session before retrying. |
|
|
209
|
+
|
|
210
|
+
### Error codes by command
|
|
211
|
+
|
|
212
|
+
#### `launch`
|
|
213
|
+
|
|
214
|
+
| `error` | When | Action |
|
|
215
|
+
| --- | --- | --- |
|
|
216
|
+
| `browser_launch_failed` | The managed browser could not be started. | Inspect `reason`/`message`; verify the host can run the browser. |
|
|
217
|
+
|
|
218
|
+
#### `attach`
|
|
219
|
+
|
|
220
|
+
| `error` | When | Action |
|
|
221
|
+
| --- | --- | --- |
|
|
222
|
+
| `browser_attach_failed` | Could not attach to the provided CDP URL. | Verify the CDP URL is reachable and exposes the protocol. |
|
|
223
|
+
|
|
224
|
+
#### `navigate`
|
|
225
|
+
|
|
226
|
+
| `error` | When | Action |
|
|
227
|
+
| --- | --- | --- |
|
|
228
|
+
| `browser_connection_failed` | See Cross-command codes. | — |
|
|
229
|
+
| `navigation_failed` | Navigation did not complete. | Retry, or re-observe to see current page state. |
|
|
230
|
+
|
|
231
|
+
#### `observe`
|
|
232
|
+
|
|
233
|
+
| `error` | When | Action |
|
|
234
|
+
| --- | --- | --- |
|
|
235
|
+
| `browser_connection_failed` | See Cross-command codes. | — |
|
|
236
|
+
| `observe_failed` | Page inspection failed (DOM or assistive runtime error). | Retry; if persistent, check the assistive runtime. |
|
|
237
|
+
| `protected_observe_blocked` | The page is under active protected exposure; observation is blocked. | Complete or cancel the protected step first. |
|
|
238
|
+
|
|
239
|
+
#### `act`
|
|
240
|
+
|
|
241
|
+
| `error` | When | Action |
|
|
242
|
+
| --- | --- | --- |
|
|
243
|
+
| `act_failed` | Generic action failure not covered by a specific code. | Check `reason`/`message`. |
|
|
244
|
+
| `action_not_allowed_for_target` | The requested action (`click`/`fill`/`type`/`select`/`press`) is not valid for this target kind. | Use an action compatible with the target's capability. |
|
|
245
|
+
| `browser_connection_failed` | See Cross-command codes. | — |
|
|
246
|
+
| `no_observable_progress` | The action ran but no DOM/UI change was detected within the wait window. | Re-observe; the target may need a different interaction. |
|
|
247
|
+
| `stale_target` | The target binding is stale at execution time. | Re-observe and rebind. |
|
|
248
|
+
| `stale_target_ref` | The passed `targetRef` no longer maps to an observed element. | Re-observe. |
|
|
249
|
+
| `target_disabled` | Element is present but disabled. | Wait for enablement or resolve the blocker. |
|
|
250
|
+
| `target_gated` | Element is gated behind an intermediate step. | Resolve the gating step first. |
|
|
251
|
+
| `target_not_actionable` | Element exists but cannot be actioned (visibility or position). | Scroll/expand the owning scope, then re-observe. |
|
|
252
|
+
| `target_readonly` | Element is read-only; `fill`/`type` are not allowed. | Use a different action or a different target. |
|
|
253
|
+
| `target_surface_inactive` | The owning scope is currently inactive (e.g. a closed modal). | Activate or expand the scope first. |
|
|
254
|
+
| `target_surface_not_live` | The owning scope is no longer live on the page. | Re-observe. |
|
|
255
|
+
| `target_surface_unavailable` | The owning scope is not currently available. | Re-observe after any UI transition. |
|
|
256
|
+
| `unknown_target_ref` | The `targetRef` was not issued by a prior `observe(...)`. | Never synthesise refs — pass back what `observe` returned. |
|
|
257
|
+
| `validation_blocked` | The target accepted the input, but page-level validation blocks continuation. | Resolve the validation error and re-observe. |
|
|
258
|
+
|
|
259
|
+
#### `extract`
|
|
260
|
+
|
|
261
|
+
| `error` | When | Action |
|
|
262
|
+
| --- | --- | --- |
|
|
263
|
+
| `browser_connection_failed` | See Cross-command codes. | — |
|
|
264
|
+
| `expired_extract_scope` | The scope ref expired (page moved past its lifetime). | Re-observe and use the new scope. |
|
|
265
|
+
| `extract_failed` | Extraction failed at runtime. | Check `reason`/`message` and retry. |
|
|
266
|
+
| `extract_output_truncated` | The assistive runtime returned a structured output that was cut off. | Raise `maxOutputTokens` in your adapter. |
|
|
267
|
+
| `invalid_extract_schema` | The passed schema is not a supported shape. | See [Extraction Schema Rules](#extraction-schema-rules). |
|
|
268
|
+
| `invalid_extract_scope` | The scope ref was provided but is not valid. | Verify the ref came from `observe(...)`. |
|
|
269
|
+
| `stale_extract_scope` | The scope ref is stale against the current DOM. | Re-observe. |
|
|
270
|
+
| `unknown_scope_ref` | The scope ref was not issued by a prior `observe(...)`. | Never synthesise refs. |
|
|
271
|
+
|
|
272
|
+
#### `screenshot`
|
|
273
|
+
|
|
274
|
+
| `error` | When | Action |
|
|
275
|
+
| --- | --- | --- |
|
|
276
|
+
| `browser_connection_failed` | See Cross-command codes. | — |
|
|
277
|
+
| `protected_screenshot_blocked` | The page is under active protected exposure; screenshot is blocked. | Complete or cancel the protected step first. |
|
|
278
|
+
| `screenshot_failed` | The screenshot attempt failed. | Check `reason`/`message`. |
|
|
279
|
+
|
|
280
|
+
#### `close`
|
|
281
|
+
|
|
282
|
+
| `error` | When | Action |
|
|
283
|
+
| --- | --- | --- |
|
|
284
|
+
| `browser_close_failed` | The browser session could not be closed cleanly. | Usually cosmetic; the process will eventually clean up. |
|
|
285
|
+
|
|
286
|
+
#### `fill`
|
|
287
|
+
|
|
288
|
+
Contract failures from `fill(...)` share a dedicated shape,
|
|
289
|
+
`AgentbrowseFillFailureResult`, with `failureSurface: 'contract'` and
|
|
290
|
+
`action: 'fill'`. Browser-level failures (stale refs, validation,
|
|
291
|
+
connection) flow through the underlying `ActResult` / `resolver.fill`
|
|
292
|
+
result instead — see `act` codes above and
|
|
293
|
+
[protected-fill.md](./protected-fill.md).
|
|
294
|
+
|
|
295
|
+
| `error` | When | Action |
|
|
296
|
+
| --- | --- | --- |
|
|
297
|
+
| `match_no_match` | `fill` received a `no_match` / `no_match_group` plan, or a subject-shape mismatch (field plan on a form, form plan on a field). | Do not retry with the same input. Re-observe or branch on the match result first. |
|
|
298
|
+
| `match_ambiguous` | `fill` received an `ambiguous` / `ambiguous_group` plan. | Ask the caller to disambiguate before filling. |
|
|
299
|
+
| `match_resolver_required` | Plan needs external resolution and no `resolver` was supplied, or the resolver is missing the required capability (`.resolve` for needs-resolution, `.fill` for grouped). | Provide a resolver adapter that implements the capability. |
|
|
300
|
+
| `match_value_unavailable` | Internal value accessor is gone. Typically means a `ready` result was serialized across a process boundary and the non-enumerable accessor was lost. | Run `resolve` → `fill` inside the same process, or ship the `needs_resolution` plan instead. |
|
|
301
|
+
| `match_artifact_unavailable` | Same failure mode as above, for grouped ready plans. | Same fix. |
|
|
302
|
+
|
|
303
|
+
See [Protected Fill](./protected-fill.md) for the separate error and
|
|
304
|
+
execution-kind vocabulary used by `fillProtectedForm(...)`.
|
|
115
305
|
|
|
116
306
|
## Error Classes
|
|
117
307
|
|
|
@@ -123,13 +313,6 @@ For code paths that want `instanceof` checks instead of string matching on
|
|
|
123
313
|
- `AssistiveStructuredOutputTruncatedError` — thrown when the assistive
|
|
124
314
|
runtime returns a structured output that was cut off mid-response.
|
|
125
315
|
|
|
126
|
-
## Core Result Shapes
|
|
127
|
-
|
|
128
|
-
All main commands use the same top-level pattern:
|
|
129
|
-
|
|
130
|
-
- success: `{ success: true, ... }`
|
|
131
|
-
- failure: `{ success: false, error, outcomeType, message, reason, ... }`
|
|
132
|
-
|
|
133
316
|
## Observe Types
|
|
134
317
|
|
|
135
318
|
### `ObserveTarget`
|
|
@@ -197,6 +380,115 @@ Fields:
|
|
|
197
380
|
- `framePath`
|
|
198
381
|
- `source`
|
|
199
382
|
|
|
383
|
+
## Match / Resolve / Fill Types
|
|
384
|
+
|
|
385
|
+
The exported types for the `match` / `resolve` / `fill` primitives.
|
|
386
|
+
Read [match-resolve-fill.md](./match-resolve-fill.md) for how they
|
|
387
|
+
compose in practice; this section is lookup-only.
|
|
388
|
+
|
|
389
|
+
### Candidate sources
|
|
390
|
+
|
|
391
|
+
- `AgentbrowseMatchSource` — union of `Record<string, AgentbrowseMatchValue>`,
|
|
392
|
+
`ReadonlyArray<AgentbrowseMatchCandidate>`,
|
|
393
|
+
`AgentbrowseMatchStore`,
|
|
394
|
+
`ReadonlyArray<AgentbrowseGroupMatchCandidate>`, or
|
|
395
|
+
`AgentbrowseGroupMatchStore`. All of these are valid `options.from`
|
|
396
|
+
values for `match(...)`.
|
|
397
|
+
- `AgentbrowseMatchValue` — `string | number`.
|
|
398
|
+
- `AgentbrowseMatchApplicability` — `{ target: 'global' | 'host'; value?: string }`.
|
|
399
|
+
- `AgentbrowseMatchCandidate` — single-field candidate with optional
|
|
400
|
+
`candidateRef`, `value`, `type`, `label`, `semanticTags`,
|
|
401
|
+
`applicability`, `resolve` plan.
|
|
402
|
+
- `AgentbrowseGroupMatchCandidate` — grouped candidate with required
|
|
403
|
+
`fieldKeys` plus optional `candidateRef`, `itemRef`, `label`,
|
|
404
|
+
`confidence`, `applicability`, `resolve` plan, `artifact`.
|
|
405
|
+
- `AgentbrowseMatchStore` — `{ entries(), read(candidateRef) }`.
|
|
406
|
+
Opaque single-field store; values stay behind `read`.
|
|
407
|
+
- `AgentbrowseGroupMatchStore` — `{ entries(), readArtifact(candidateRef) }`.
|
|
408
|
+
Opaque grouped store; artifacts stay behind `readArtifact`.
|
|
409
|
+
|
|
410
|
+
### Match result union
|
|
411
|
+
|
|
412
|
+
`AgentbrowseMatchResult` is a discriminated union over `kind`:
|
|
413
|
+
|
|
414
|
+
- `AgentbrowseReadyMatchResult` — `kind: 'ready'` (single target).
|
|
415
|
+
- `AgentbrowseNeedsResolutionMatchResult` — `kind: 'needs_resolution'`
|
|
416
|
+
with `plan: AgentbrowseResolutionPlan`.
|
|
417
|
+
- `AgentbrowseAmbiguousMatchResult` — `kind: 'ambiguous'` with
|
|
418
|
+
`candidates: string[]`.
|
|
419
|
+
- `AgentbrowseNoMatchResult` — `kind: 'no_match'` with a stable
|
|
420
|
+
`reason`: `'protected_target' | 'no_candidate' | 'scope_ineligible' | 'incompatible_shape' | 'low_confidence'`.
|
|
421
|
+
- `AgentbrowseReadyGroupMatchResult` — `kind: 'ready_group'`.
|
|
422
|
+
- `AgentbrowseNeedsResolutionGroupMatchResult` — `kind: 'needs_resolution_group'`
|
|
423
|
+
with `plan: AgentbrowseGroupResolutionPlan`.
|
|
424
|
+
- `AgentbrowseAmbiguousGroupMatchResult` — `kind: 'ambiguous_group'`.
|
|
425
|
+
- `AgentbrowseNoGroupMatchResult` — `kind: 'no_match_group'` with the
|
|
426
|
+
same `reason` vocabulary.
|
|
427
|
+
|
|
428
|
+
`AgentbrowseResolvableMatchResult` is the narrower union of
|
|
429
|
+
`'needs_resolution' | 'needs_resolution_group'` — what `resolve(...)`
|
|
430
|
+
actually hands to your adapter.
|
|
431
|
+
|
|
432
|
+
### Resolution plans
|
|
433
|
+
|
|
434
|
+
- `AgentbrowseResolutionPlan` — `{ targetRef, candidateRef, fieldKey, type?, resolve }`.
|
|
435
|
+
- `AgentbrowseGroupResolutionPlan` — `{ fillRef, pageRef, scopeRef?, purpose, candidateRef, itemRef?, fieldKeys, resolve }`.
|
|
436
|
+
- `AgentbrowseMatchResolutionRequest` — `{ kind: string; key?: string; params?: Record<string, unknown> }`.
|
|
437
|
+
The `resolve` field on a candidate or plan. AgentBrowse does not
|
|
438
|
+
interpret `kind` or `key` — they are opaque to the core and meaningful
|
|
439
|
+
only to your adapter.
|
|
440
|
+
|
|
441
|
+
### Resolved resources
|
|
442
|
+
|
|
443
|
+
- `AgentbrowseResolvedResource` — `AgentbrowseResolvedValueResource | AgentbrowseResolvedArtifactResource`.
|
|
444
|
+
- `AgentbrowseResolvedValueResource` — `{ kind: 'value'; value }`.
|
|
445
|
+
- `AgentbrowseResolvedArtifactResource` — `{ kind: 'artifact'; artifact; itemRef?; requestId?; resolutionPath?; claimedAt? }`.
|
|
446
|
+
- `AgentbrowseReadyGroupFillInput` — the shape `resolver.fill` receives:
|
|
447
|
+
`{ candidateRef, itemRef?, fieldKeys, artifact, requestId?, resolutionPath?, claimedAt? }`.
|
|
448
|
+
|
|
449
|
+
### Resolver adapter
|
|
450
|
+
|
|
451
|
+
Two exported interfaces. The `{ resolver }` slot on `fill(...)` accepts
|
|
452
|
+
either via a union; `resolve(plan, { with })` only accepts the main
|
|
453
|
+
resolver.
|
|
454
|
+
|
|
455
|
+
```ts
|
|
456
|
+
interface AgentbrowseMatchResolver {
|
|
457
|
+
resolve(plan): Promise<AgentbrowseResolvedResource>;
|
|
458
|
+
resolveBatch?(plans): Promise<ReadonlyArray<AgentbrowseResolvedResource>>;
|
|
459
|
+
fill?(session, subject, ready): Promise<Record<string, unknown> & { success: boolean }>;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
interface AgentbrowseGroupFillHandler {
|
|
463
|
+
fill(session, subject, ready): Promise<Record<string, unknown> & { success: boolean }>;
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
- `AgentbrowseMatchResolver` — full adapter. `resolve` is required;
|
|
468
|
+
`resolveBatch` and `fill` are optional. Used by `resolve(plan, { with })`
|
|
469
|
+
and by `fill(...)` for all plan kinds.
|
|
470
|
+
- `AgentbrowseGroupFillHandler` — narrow handler used only at the
|
|
471
|
+
`fill(...)` boundary when the plan is `ready_group` and no resolution
|
|
472
|
+
is needed. A handler is not accepted by `resolve(...)`.
|
|
473
|
+
|
|
474
|
+
At runtime, `fill(...)` picks the right capability via an internal type
|
|
475
|
+
guard (`hasResolveCapability` / `hasGroupFillCapability`). When a
|
|
476
|
+
capability the current plan needs is missing on the passed object,
|
|
477
|
+
`fill(...)` returns a typed `match_resolver_required` failure instead
|
|
478
|
+
of throwing.
|
|
479
|
+
|
|
480
|
+
See [match-resolve-fill.md → Resolver Interface](./match-resolve-fill.md#resolver-interface)
|
|
481
|
+
for examples of each shape.
|
|
482
|
+
|
|
483
|
+
### Fill result
|
|
484
|
+
|
|
485
|
+
- `AgentbrowseFillResult` — `ActResult | AgentbrowseFillFailureResult | (Record<string, unknown> & { success: boolean })`.
|
|
486
|
+
Single-target fill returns `ActResult`; grouped fill returns whatever
|
|
487
|
+
your `resolver.fill` returned; contract failures return
|
|
488
|
+
`AgentbrowseFillFailureResult`.
|
|
489
|
+
- `AgentbrowseFillFailureResult` — `{ success: false; failureSurface: 'contract'; error; outcomeType; message; reason; targetRef?; fillRef?; action: 'fill' }`.
|
|
490
|
+
See the [`fill` error table](#fill) above for `error` codes.
|
|
491
|
+
|
|
200
492
|
## Ref Glossary
|
|
201
493
|
|
|
202
494
|
- `ref`
|
|
@@ -58,6 +58,9 @@ this usually means:
|
|
|
58
58
|
|
|
59
59
|
1. Convert the Zod schema to JSON Schema (e.g. with
|
|
60
60
|
`@browserbasehq/stagehand`'s `toJsonSchema`, or your own helper).
|
|
61
|
+
`@browserbasehq/stagehand` is a direct dependency of this package, so
|
|
62
|
+
`toJsonSchema` is available without a separate install. Alternatives
|
|
63
|
+
like `zod-to-json-schema` work too.
|
|
61
64
|
2. Pass it as `response_format: { type: 'json_schema', json_schema: { ... } }`.
|
|
62
65
|
3. Parse `choices[0].message.content` and return `{ data, usage? }`.
|
|
63
66
|
|
|
@@ -99,6 +102,9 @@ by hand.
|
|
|
99
102
|
|
|
100
103
|
## Recommended Setup
|
|
101
104
|
|
|
105
|
+
The preferred path is a per-client runtime: pass your runtime into
|
|
106
|
+
`createAgentbrowseClient({ assistiveRuntime })` and reuse that client.
|
|
107
|
+
|
|
102
108
|
```ts
|
|
103
109
|
import { createAgentbrowseClient } from '@mercuryo-ai/agentbrowse';
|
|
104
110
|
|
|
@@ -106,16 +112,38 @@ const client = createAgentbrowseClient({
|
|
|
106
112
|
assistiveRuntime: createOpenAiCompatibleAssistiveRuntime({
|
|
107
113
|
baseUrl: 'https://api.openai.com/v1',
|
|
108
114
|
apiKey: process.env.OPENAI_API_KEY!,
|
|
109
|
-
model
|
|
115
|
+
// Any OpenAI-compatible model that supports structured outputs.
|
|
116
|
+
model: process.env.OPENAI_MODEL ?? '<your-model>',
|
|
110
117
|
}),
|
|
111
118
|
});
|
|
112
119
|
```
|
|
113
120
|
|
|
114
121
|
This pattern works well when:
|
|
115
122
|
|
|
116
|
-
- your app is multi-tenant
|
|
117
|
-
- you run parallel tests
|
|
118
|
-
- different consumers in one process need different LLM settings
|
|
123
|
+
- your app is multi-tenant;
|
|
124
|
+
- you run parallel tests;
|
|
125
|
+
- different consumers in one process need different LLM settings.
|
|
126
|
+
|
|
127
|
+
### Per-client vs global runtime
|
|
128
|
+
|
|
129
|
+
| Setup | When to use |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `createAgentbrowseClient({ assistiveRuntime })` | Default. Keeps the runtime scoped to one client, works with multi-tenant and parallel scenarios. |
|
|
132
|
+
| `configureAgentbrowseAssistiveRuntime(runtime)` | Fallback for small scripts and single-tenant processes — sets one global runtime for the whole process. Not recommended when multiple consumers may coexist. |
|
|
133
|
+
|
|
134
|
+
Global-runtime shape:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { configureAgentbrowseAssistiveRuntime } from '@mercuryo-ai/agentbrowse';
|
|
138
|
+
|
|
139
|
+
configureAgentbrowseAssistiveRuntime(
|
|
140
|
+
createOpenAiCompatibleAssistiveRuntime({
|
|
141
|
+
baseUrl: 'https://api.openai.com/v1',
|
|
142
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
143
|
+
model: process.env.OPENAI_MODEL ?? '<your-model>',
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
```
|
|
119
147
|
|
|
120
148
|
## OpenAI-Compatible Helper Example
|
|
121
149
|
|
|
@@ -232,21 +260,18 @@ Examples:
|
|
|
232
260
|
- OpenRouter base URL:
|
|
233
261
|
`https://openrouter.ai/api/v1`
|
|
234
262
|
|
|
235
|
-
## Small Script Fallback
|
|
236
|
-
|
|
237
|
-
For small scripts, you can also use:
|
|
238
|
-
|
|
239
|
-
```ts
|
|
240
|
-
import { configureAgentbrowseAssistiveRuntime } from '@mercuryo-ai/agentbrowse';
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
This is a convenience fallback, not the preferred embedded pattern.
|
|
244
|
-
|
|
245
263
|
## What Happens Without Assistive Runtime
|
|
246
264
|
|
|
247
|
-
- `extract(...)` cannot run successfully
|
|
265
|
+
- `extract(...)` cannot run successfully.
|
|
248
266
|
- `observe(session, goal)` still runs, but quality may be lower because
|
|
249
|
-
AgentBrowse falls back to local heuristics instead of LLM-assisted
|
|
267
|
+
AgentBrowse falls back to local heuristics instead of LLM-assisted
|
|
268
|
+
ranking.
|
|
269
|
+
- `fillProtectedForm(...)` returns
|
|
270
|
+
`{ kind: 'unexpected_error', reason: 'assisted_value_resolution_failed' }`
|
|
271
|
+
for fields that require LLM-assisted resolution (split `full_name` into
|
|
272
|
+
given/family, localised dropdown values like nationality on a
|
|
273
|
+
non-English page, or any field pinned to the `llm_assisted` policy).
|
|
274
|
+
See [Protected Fill Guide](./protected-fill.md#split-fields-and-assistive-runtime).
|
|
250
275
|
|
|
251
276
|
## Testing Runtime
|
|
252
277
|
|
package/docs/getting-started.md
CHANGED
|
@@ -42,12 +42,14 @@ invalidates them:
|
|
|
42
42
|
|
|
43
43
|
After any of the above, call `observe(...)` again and use the new refs.
|
|
44
44
|
|
|
45
|
-
At a high level, AgentBrowse has
|
|
45
|
+
At a high level, AgentBrowse has four kinds of behavior:
|
|
46
46
|
|
|
47
47
|
- normal browser execution for `launch`, `navigate`, `observe`, `act`,
|
|
48
48
|
`status`, `screenshot`, and `close`
|
|
49
49
|
- assistive page understanding for `extract` and some goal-based
|
|
50
50
|
`observe(session, goal)` calls
|
|
51
|
+
- deterministic field data-plane for deciding which caller-supplied
|
|
52
|
+
value belongs in which observed field (`match`, `resolve`, `fill`)
|
|
51
53
|
- protected fill for applying sensitive values you already have through a
|
|
52
54
|
guarded form execution path
|
|
53
55
|
|
|
@@ -155,6 +157,22 @@ serve different intents:
|
|
|
155
157
|
- `observe(session)` is for general page inspection
|
|
156
158
|
- `observe(session, goal)` is for a focused question
|
|
157
159
|
|
|
160
|
+
These examples share a shape that works well: each names one control,
|
|
161
|
+
optionally anchored to a surface. A useful goal looks like
|
|
162
|
+
`"find <target> in <surface>"`:
|
|
163
|
+
|
|
164
|
+
- one target — a single field, button, or grid cell
|
|
165
|
+
- one surface — the active form, the open datepicker, the visible banner
|
|
166
|
+
- one step — the goal describes what the next `act` will target,
|
|
167
|
+
not the rest of the plan
|
|
168
|
+
|
|
169
|
+
When the task takes several steps, run one `observe` per step:
|
|
170
|
+
|
|
171
|
+
1. `observe(session, "find the date picker trigger in the top search form")`
|
|
172
|
+
2. `act(session, trigger.ref, "click")`
|
|
173
|
+
3. `observe(session, "find May 5, 2026 in the open calendar")`
|
|
174
|
+
4. `act(session, cell.ref, "click")`
|
|
175
|
+
|
|
158
176
|
### `act(session, targetRef, action, value?)`
|
|
159
177
|
|
|
160
178
|
Executes a browser action against a `targetRef` returned by `observe(...)`.
|
|
@@ -197,6 +215,31 @@ Closes the browser session.
|
|
|
197
215
|
This also terminates the internal sticky owner. Repeated closes and already-
|
|
198
216
|
dead owner hosts are treated as idempotent.
|
|
199
217
|
|
|
218
|
+
### `match` / `resolve` / `fill`
|
|
219
|
+
|
|
220
|
+
Three primitives for the «key–value pairs into an observed form» problem.
|
|
221
|
+
Instead of calling `act(session, ref, 'fill', value)` by hand, the
|
|
222
|
+
primitives let you hand a source of candidate values to `match(...)`,
|
|
223
|
+
resolve externally stored values through a caller-supplied adapter, and
|
|
224
|
+
apply the result to the browser deterministically — without the values
|
|
225
|
+
passing through LLM prompts or public result objects.
|
|
226
|
+
|
|
227
|
+
The typical shape is `match → (resolve) → fill`:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
import { match, resolve, fill } from '@mercuryo-ai/agentbrowse';
|
|
231
|
+
|
|
232
|
+
const matched = await match(emailTarget, {
|
|
233
|
+
from: { email: 'traveler@example.com' },
|
|
234
|
+
});
|
|
235
|
+
await fill(session, emailTarget, matched);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
See the dedicated [Match / Resolve / Fill Guide](./match-resolve-fill.md)
|
|
239
|
+
for the full mental model, walk-throughs (value in hand, external
|
|
240
|
+
lookup, batch, grouped protected forms), and the design rules (no raw
|
|
241
|
+
values in public results, stable resolved refs, adapter boundary).
|
|
242
|
+
|
|
200
243
|
## How To Handle Results
|
|
201
244
|
|
|
202
245
|
All main commands use the same broad pattern:
|
|
@@ -264,6 +307,7 @@ See:
|
|
|
264
307
|
## Next Docs
|
|
265
308
|
|
|
266
309
|
- [API Reference](./api-reference.md)
|
|
310
|
+
- [Match / Resolve / Fill Guide](./match-resolve-fill.md)
|
|
267
311
|
- [Configuration Guide](./configuration.md)
|
|
268
312
|
- [Assistive Runtime Guide](./assistive-runtime.md)
|
|
269
313
|
- [Protected Fill Guide](./protected-fill.md)
|
|
@@ -13,9 +13,38 @@ integration.
|
|
|
13
13
|
- use `observeResult.targets` as the default flat inventory
|
|
14
14
|
- use `target.ref` as the input to `act(...)`
|
|
15
15
|
- pass a plain schema object or a Zod schema to `extract(...)`
|
|
16
|
-
- branch on stable top-level `error` codes, not on `reason`
|
|
16
|
+
- branch on stable top-level `error` codes, not on `reason` — the
|
|
17
|
+
per-command list lives in
|
|
18
|
+
[`api-reference.md` → Error codes by command](./api-reference.md#error-codes-by-command)
|
|
17
19
|
- treat `reason` as human-readable diagnostics, not as a stable switch key
|
|
18
20
|
|
|
21
|
+
## Match / Resolve / Fill
|
|
22
|
+
|
|
23
|
+
- branch on `match(...)` result `kind` — never infer from the presence
|
|
24
|
+
of individual fields on the result object
|
|
25
|
+
- default match results carry `valueRef` / `artifactRef` strings, not
|
|
26
|
+
raw values; the accessor that dereferences them is a non-enumerable
|
|
27
|
+
symbol on the `ready` result and does not survive JSON serialization
|
|
28
|
+
or `structuredClone`. Do not serialize ready results across process
|
|
29
|
+
boundaries — ship the `needs_resolution` plan instead and let the
|
|
30
|
+
downstream side run `resolve → fill` in one shot
|
|
31
|
+
- the main `AgentbrowseMatchResolver` has a required `resolve` plus
|
|
32
|
+
optional `resolveBatch` and optional `fill`. A narrow
|
|
33
|
+
`AgentbrowseGroupFillHandler` with just `fill` is also accepted in
|
|
34
|
+
the `{ resolver }` slot on `fill(...)` and is the right shape when
|
|
35
|
+
the caller already has a ready grouped artifact and does not fetch
|
|
36
|
+
anything. `resolve(plan, { with })` only accepts the main interface.
|
|
37
|
+
Runtime `fill(...)` returns `match_resolver_required` when the passed
|
|
38
|
+
object lacks a capability the current plan needs
|
|
39
|
+
- batch `resolve([...])` preserves input order — downstream code can
|
|
40
|
+
rebuild the `target → ready` mapping by index
|
|
41
|
+
- use `@mercuryo-ai/agentbrowse/testing` fixture builders
|
|
42
|
+
(`createFixtureMatchStore`, `createFixtureGroupStore`,
|
|
43
|
+
`createFixtureResolver`, `fixtureResolvedValue`,
|
|
44
|
+
`fixtureResolvedArtifact`) in unit tests instead of fabricating match
|
|
45
|
+
results by hand — hand-built results bypass the accessor pattern and
|
|
46
|
+
fail to fill
|
|
47
|
+
|
|
19
48
|
## Assistive Runtime
|
|
20
49
|
|
|
21
50
|
- the assistive runtime adapter receives `args.options`
|
|
@@ -25,8 +54,8 @@ integration.
|
|
|
25
54
|
|
|
26
55
|
## Testing
|
|
27
56
|
|
|
28
|
-
- use `@mercuryo-ai/agentbrowse/testing` for the
|
|
29
|
-
runtime helper
|
|
57
|
+
- use `@mercuryo-ai/agentbrowse/testing` for both the fetch-backed
|
|
58
|
+
assistive runtime helper and the match/resolve/fill fixture builders
|
|
30
59
|
- do not depend on internal fixtures or unexported runtime-state helpers
|
|
31
60
|
|
|
32
61
|
## Packaging
|