@orkestrel/browser 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/src/browser/index.d.ts +77 -19
- package/dist/src/browser/index.js +361 -21
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +963 -173
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +354 -78
- package/dist/src/core/index.d.ts +354 -78
- package/dist/src/core/index.js +957 -175
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +36 -11
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +2 -2
- package/dist/src/server/index.d.ts +2 -2
- package/dist/src/server/index.js +36 -11
- package/dist/src/server/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
> and publishes them as agent tools, an in-page face that drives a DOM document with native APIs,
|
|
6
6
|
> and a Node runtime that finds, launches, and connects to the browser itself.
|
|
7
7
|
|
|
8
|
-
Connect to a running browser or launch one with the `createBrowser` function, open a page, and drive it through stable element references and trusted input. Read the page as Markdown in bounded slices, and hand the whole vocabulary to an agent as `@orkestrel/tool` tools with `createBrowserToolset`. Inside a page, `createDocumentToolset` drives a DOM document with native APIs, and `createSocketCDPTransport` carries the core client over the browser's own `WebSocket`. Record a journey, one user intent kept as JSON, from a model's tool calls or a person's gestures on a page, then list, edit, replay, and forget it through the six journey tools, or compile it with `compileBrowserJourney` into a module a developer runs and customizes. Part of the `@orkestrel` line.
|
|
8
|
+
Connect to a running browser or launch one with the `createBrowser` function, open a page, and drive it through stable element references and trusted input. Read the whole captured page as Markdown or plain text in bounded slices, and hand the whole vocabulary to an agent as `@orkestrel/tool` tools with `createBrowserToolset`. Inside a page, `createDocumentToolset` drives a DOM document with native APIs, and `createSocketCDPTransport` carries the core client over the browser's own `WebSocket`. Record a journey, one user intent kept as JSON, from a model's tool calls or a person's gestures on a page, then list, edit, replay, and forget it through the six journey tools, or compile it with `compileBrowserJourney` into a module a developer runs and customizes. Part of the `@orkestrel` line.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -40,7 +40,8 @@ const [save] = await page.elements.find({ role: 'button', name: 'Save' })
|
|
|
40
40
|
await save?.click()
|
|
41
41
|
await page.wait('Saved')
|
|
42
42
|
const reading = await page.read()
|
|
43
|
-
reading.markdown({ limit: 4_000 }) // { text, offset, total }
|
|
43
|
+
reading.markdown({ limit: 4_000 }) // { text, offset, total }; whole page by default
|
|
44
|
+
reading.text({ distill: true }) // main content as plain text
|
|
44
45
|
await page.screenshot({ path: 'example.png' })
|
|
45
46
|
await browser.destroy()
|
|
46
47
|
```
|
|
@@ -53,7 +54,9 @@ import { createToolManager } from '@orkestrel/tool'
|
|
|
53
54
|
|
|
54
55
|
const toolset = createBrowserToolset(page, { tools: createToolManager() })
|
|
55
56
|
await toolset.start()
|
|
56
|
-
await toolset.tools.execute({ id: '1', name: 'look', arguments: {
|
|
57
|
+
await toolset.tools.execute({ id: '1', name: 'look', arguments: { search: 'Email' } })
|
|
58
|
+
await toolset.tools.execute({ id: '2', name: 'read', arguments: { search: 'delivery' } })
|
|
59
|
+
await toolset.tools.execute({ id: '3', name: 'plain', arguments: { search: 'confirmation' } })
|
|
57
60
|
await toolset.destroy()
|
|
58
61
|
```
|
|
59
62
|
|
|
@@ -2,7 +2,6 @@ import type { BrowserCallOptions } from '@orkestrel/browser';
|
|
|
2
2
|
import type { BrowserElementInterface } from '@orkestrel/browser';
|
|
3
3
|
import type { BrowserElementManagerInterface } from '@orkestrel/browser';
|
|
4
4
|
import type { BrowserElementQuery } from '@orkestrel/browser';
|
|
5
|
-
import type { BrowserElementWaitOptions } from '@orkestrel/browser';
|
|
6
5
|
import type { BrowserEpochFunction } from '@orkestrel/browser';
|
|
7
6
|
import type { BrowserOutline } from '@orkestrel/browser';
|
|
8
7
|
import type { BrowserOutlineOptions } from '@orkestrel/browser';
|
|
@@ -11,6 +10,7 @@ import type { BrowserReadingInterface } from '@orkestrel/browser';
|
|
|
11
10
|
import type { BrowserToolsetInterface } from '@orkestrel/browser';
|
|
12
11
|
import type { BrowserToolsetOptions } from '@orkestrel/browser';
|
|
13
12
|
import type { BrowserViewInterface } from '@orkestrel/browser';
|
|
13
|
+
import type { BrowserWaitOptions } from '@orkestrel/browser';
|
|
14
14
|
import type { CDPTransportEventMap } from '@orkestrel/browser';
|
|
15
15
|
import type { CDPTransportInterface } from '@orkestrel/browser';
|
|
16
16
|
import type { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
@@ -36,6 +36,14 @@ export declare const BROWSER_CONTEXT_TARGETS: ReadonlySet<string>;
|
|
|
36
36
|
*/
|
|
37
37
|
export declare const BROWSER_DOCUMENT_TIMEOUT_MS = 5000;
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Names the roles whose ARIA expansion state the DOM outline reads.
|
|
41
|
+
*
|
|
42
|
+
* @remarks
|
|
43
|
+
* The role set follows the accessibility-tree reading from Chromium 141.0.7390.37.
|
|
44
|
+
*/
|
|
45
|
+
export declare const BROWSER_EXPANDED_ROLES: ReadonlySet<string>;
|
|
46
|
+
|
|
39
47
|
/**
|
|
40
48
|
* Maps an HTML element to the ARIA role the HTML Accessibility API Mappings specification gives
|
|
41
49
|
* it when it carries no `role` attribute.
|
|
@@ -58,6 +66,14 @@ export declare const BROWSER_IMPLICIT_ROLES: ReadonlyMap<string, string>;
|
|
|
58
66
|
*/
|
|
59
67
|
export declare const BROWSER_INTERACTIVE_CONTENT = "a[href], audio[controls], button, details, embed, iframe, img[usemap], img[controls], input:not([type=\"hidden\" i]), label, select, textarea, video[controls]";
|
|
60
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Names the roles whose selection state the DOM outline reads.
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
* The role set follows the accessibility-tree reading from Chromium 141.0.7390.37.
|
|
74
|
+
*/
|
|
75
|
+
export declare const BROWSER_SELECTED_ROLES: ReadonlySet<string>;
|
|
76
|
+
|
|
61
77
|
/** Names the `input` type states whose value an untrusted `fill` sets as typed text. */
|
|
62
78
|
export declare const BROWSER_TYPED_INPUTS: ReadonlySet<string>;
|
|
63
79
|
|
|
@@ -165,8 +181,10 @@ export declare interface BrowserDOMElementInterface extends BrowserElementInterf
|
|
|
165
181
|
* wrapper reports that latest capture, also after the manager drops the reference. A reference
|
|
166
182
|
* and a reading from any walked document record that document's epoch, which advances on its own
|
|
167
183
|
* navigation events and on the view's; that document's `pagehide` drops its references. A form
|
|
168
|
-
* carrying a `toolname` attribute renders `[tool=NAME]` after its role and name. A
|
|
169
|
-
*
|
|
184
|
+
* carrying a `toolname` attribute renders `[tool=NAME]` after its role and name. A row carries
|
|
185
|
+
* `focused` when its element is the active element of its own document or shadow root. Rows carry
|
|
186
|
+
* pressed, expanded, and selected states through the Chromium mapping in `readBrowserStates`.
|
|
187
|
+
* A `select` row is followed by one `option` row per option, named by its label. Whitespace between two texts of
|
|
170
188
|
* one block renders as one space, as a rendered `br` between them does, and texts with neither
|
|
171
189
|
* between them stay joined. A CSS query
|
|
172
190
|
* searches the document the view drives, not its child documents or shadow trees. After the
|
|
@@ -190,7 +208,7 @@ export declare class BrowserDOMElementManager implements BrowserElementManagerIn
|
|
|
190
208
|
constructor(input: BrowserDOMElementManagerInput);
|
|
191
209
|
outline(options?: BrowserOutlineOptions): Promise<BrowserOutline>;
|
|
192
210
|
find(query: BrowserElementQuery, options?: BrowserCallOptions): Promise<readonly BrowserDOMElementInterface[]>;
|
|
193
|
-
wait(query: BrowserElementQuery, options?:
|
|
211
|
+
wait(query: BrowserElementQuery, options?: BrowserWaitOptions): Promise<readonly BrowserDOMElementInterface[]>;
|
|
194
212
|
element(reference: string): BrowserDOMElementInterface | undefined;
|
|
195
213
|
elements(): readonly BrowserDOMElementInterface[];
|
|
196
214
|
clear(): void;
|
|
@@ -246,7 +264,7 @@ export declare class BrowserDOMView implements BrowserDOMViewInterface {
|
|
|
246
264
|
get elements(): BrowserElementManagerInterface<BrowserDOMElementInterface>;
|
|
247
265
|
title(options?: BrowserCallOptions): Promise<string>;
|
|
248
266
|
read(options?: BrowserCallOptions): Promise<BrowserReadingInterface>;
|
|
249
|
-
wait(text: string, options?:
|
|
267
|
+
wait(text: string, options?: BrowserWaitOptions): Promise<void>;
|
|
250
268
|
destroy(): void;
|
|
251
269
|
}
|
|
252
270
|
|
|
@@ -272,14 +290,15 @@ export declare interface BrowserDOMViewOptions {
|
|
|
272
290
|
}
|
|
273
291
|
|
|
274
292
|
/**
|
|
275
|
-
* Parks one condition on DOM mutations until it holds, with one deadline and
|
|
293
|
+
* Parks one condition on DOM mutations and finished transitions and animations until it holds, with one deadline and coalesced wake tasks.
|
|
276
294
|
*
|
|
277
295
|
* @remarks
|
|
278
296
|
* The wait observes every root `roots` returns, each through a `MutationObserver` of that root's
|
|
279
|
-
* realm, and re-reads the roots after every mutation batch
|
|
280
|
-
*
|
|
297
|
+
* realm, and re-reads the roots after every mutation batch, every capture-phase `load`, and
|
|
298
|
+
* the task after a `BROWSER_WAIT_EVENTS` event in an observed root: a same-origin
|
|
299
|
+
* frame or an open shadow root that appears joins the observation,
|
|
281
300
|
* and a root that departed (a replaced frame document, a removed shadow root) leaves it, with its
|
|
282
|
-
* observer disconnected and its
|
|
301
|
+
* observer disconnected and its listeners removed. The check runs before the wait parks and
|
|
283
302
|
* again after every subscription, and no check runs once the deadline, counted from `start`, has
|
|
284
303
|
* passed, which the wait reads again after `roots` returns. The wait settles one time: on the
|
|
285
304
|
* check's first value, on the signal's abort with its reason, at the deadline with
|
|
@@ -291,9 +310,9 @@ export declare interface BrowserDOMViewOptions {
|
|
|
291
310
|
* observer, listener, or further check behind.
|
|
292
311
|
*
|
|
293
312
|
* A shadow root attached after the wait began is a declared limit: attaching one fires no
|
|
294
|
-
* mutation record and no event, so the wait discovers it at the next mutation
|
|
295
|
-
* observes, and a match inserted into it with no other
|
|
296
|
-
* deadline. The wait never polls to close that gap.
|
|
313
|
+
* mutation record and no event, so the wait discovers it at the next mutation batch, `load`,
|
|
314
|
+
* or `BROWSER_WAIT_EVENTS` event it observes, and a match inserted into it with no other
|
|
315
|
+
* observed change is not seen before the deadline. The wait never polls to close that gap.
|
|
297
316
|
*
|
|
298
317
|
* @example
|
|
299
318
|
* ```ts
|
|
@@ -313,7 +332,7 @@ export declare class BrowserDOMWait<T> implements BrowserDOMWaitInterface<T> {
|
|
|
313
332
|
execute(): Promise<T>;
|
|
314
333
|
}
|
|
315
334
|
|
|
316
|
-
/** Settles one wait parked on DOM mutations. */
|
|
335
|
+
/** Settles one wait parked on DOM mutations and finished transitions and animations. */
|
|
317
336
|
export declare interface BrowserDOMWaitInterface<T> {
|
|
318
337
|
/** The roots the wait observes at this moment; empty before it parks and after it settles. */
|
|
319
338
|
readonly roots: readonly Node[];
|
|
@@ -325,11 +344,11 @@ export declare interface BrowserDOMWaitInterface<T> {
|
|
|
325
344
|
}
|
|
326
345
|
|
|
327
346
|
/**
|
|
328
|
-
* Describes one wait parked on DOM mutations.
|
|
347
|
+
* Describes one wait parked on DOM mutations and finished transitions and animations.
|
|
329
348
|
*
|
|
330
349
|
* @remarks
|
|
331
350
|
* - `roots` — returns the documents and shadow roots whose mutations re-run the check; the wait
|
|
332
|
-
* re-reads it after every mutation batch and every `
|
|
351
|
+
* re-reads it after every mutation batch, every `load`, and every `BROWSER_WAIT_EVENTS` event in an observed root, observing the
|
|
333
352
|
* roots that appeared and releasing the ones that departed, and a `pagehide` in the first
|
|
334
353
|
* root's window fails the wait
|
|
335
354
|
* - `check` — returns the value the wait settles on, or `undefined` to keep waiting
|
|
@@ -506,7 +525,7 @@ export declare function createBrowserDOMView(options: BrowserDOMViewOptions): Br
|
|
|
506
525
|
*
|
|
507
526
|
* @remarks
|
|
508
527
|
* The toolset runs over a view {@link createBrowserDOMView} creates for `document`, so it
|
|
509
|
-
* advertises `look`, `read`, `click`, `type`, and `wait`, and a click or type receipt ends with
|
|
528
|
+
* advertises `look`, `read`, `plain`, `click`, `type`, and `wait`, and a click or type receipt ends with
|
|
510
529
|
* ` (untrusted event)`. `source` supplies page tools, which the toolset adopts during `start()`
|
|
511
530
|
* and again on every `change`; `toolset.native` never includes them, so publishing it to a
|
|
512
531
|
* registry leaves that registry's own tools alone. The view belongs to the toolset: `destroy()`
|
|
@@ -526,7 +545,7 @@ export declare function createBrowserDOMView(options: BrowserDOMViewOptions): Br
|
|
|
526
545
|
* ```ts
|
|
527
546
|
* const toolset = createDocumentToolset({ document: frame.contentDocument, source: bridge })
|
|
528
547
|
* await toolset.start()
|
|
529
|
-
* await toolset.tools.execute({ id: '1', name: 'look', arguments: {
|
|
548
|
+
* await toolset.tools.execute({ id: '1', name: 'look', arguments: { search: 'form' } })
|
|
530
549
|
* ```
|
|
531
550
|
*/
|
|
532
551
|
export declare function createDocumentToolset(options: BrowserDocumentToolsetOptions): BrowserToolsetInterface;
|
|
@@ -721,15 +740,16 @@ export declare function matchesBrowserPopup(element: Element): boolean;
|
|
|
721
740
|
export declare function readBrowserBlock(element: Element | null, root: Node): Node;
|
|
722
741
|
|
|
723
742
|
/**
|
|
724
|
-
* Reads the URL, title, and
|
|
743
|
+
* Reads the URL, title, and rendered markup a DOM reading is built from, refusing a capture
|
|
725
744
|
* over the result limit before any parse.
|
|
726
745
|
*
|
|
727
746
|
* @remarks
|
|
728
747
|
* The measure is the length of `JSON.stringify({ url, title, html })`, the form the CDP capture
|
|
729
748
|
* guard compares with `BROWSER_RESULT_LIMIT`, so a character JSON escapes counts as its escape
|
|
730
749
|
* sequence. A reading a caller builds with `createBrowserReading` passes through no limit.
|
|
750
|
+
* {@link BrowserReadingInput} defines the inert capture, lowering, redaction, and limits.
|
|
731
751
|
*
|
|
732
|
-
* @param node - The
|
|
752
|
+
* @param node - The root whose rendered markup is captured; its owner document supplies `URL`
|
|
733
753
|
* and `title`
|
|
734
754
|
* @returns The capture's `url`, `title`, and `html`
|
|
735
755
|
* @throws Thrown as a `BrowserResultLimitError` when the serialized capture is longer than
|
|
@@ -778,6 +798,44 @@ export declare function readBrowserContent(root: Element | ShadowRoot, context?:
|
|
|
778
798
|
*/
|
|
779
799
|
export declare function readBrowserParent(element: Element): Element | null;
|
|
780
800
|
|
|
801
|
+
/**
|
|
802
|
+
* Reads the pressed, expanded, and selected states the DOM outline assigns to an element's role.
|
|
803
|
+
*
|
|
804
|
+
* @remarks
|
|
805
|
+
* Only buttons carry pressed state. Expansion follows `BROWSER_EXPANDED_ROLES`, with native
|
|
806
|
+
* single selects always collapsed. Selection follows `BROWSER_SELECTED_ROLES`: an ARIA token
|
|
807
|
+
* overrides native option selectedness, and other elements without a token omit selection. Tokens are not
|
|
808
|
+
* trimmed; values other than `false` are true, except the pressed token `mixed`.
|
|
809
|
+
*
|
|
810
|
+
* @param element - The element whose attributes and native state are read
|
|
811
|
+
* @param role - Its computed accessibility role
|
|
812
|
+
* @returns Present states, including false, with pressed represented as a tristate string
|
|
813
|
+
*
|
|
814
|
+
* @example
|
|
815
|
+
* ```ts
|
|
816
|
+
* const button = document.createElement('button')
|
|
817
|
+
* button.setAttribute('aria-pressed', 'mixed')
|
|
818
|
+
* readBrowserStates(button, 'button') // { pressed: 'mixed' }
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
export declare function readBrowserStates(element: Element, role: string): Readonly<Record<string, string | boolean>>;
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Reads a lowercased ARIA token, preserving whitespace and treating empty or undefined tokens as absent.
|
|
825
|
+
*
|
|
826
|
+
* @param element - The element carrying the attribute
|
|
827
|
+
* @param attribute - The ARIA attribute name
|
|
828
|
+
* @returns The lowercased token, or `undefined` for a missing, empty, or `undefined` attribute
|
|
829
|
+
*
|
|
830
|
+
* @example
|
|
831
|
+
* ```ts
|
|
832
|
+
* const button = document.createElement('button')
|
|
833
|
+
* button.setAttribute('aria-pressed', 'TRUE')
|
|
834
|
+
* readBrowserToken(button, 'aria-pressed') // 'true'
|
|
835
|
+
* ```
|
|
836
|
+
*/
|
|
837
|
+
export declare function readBrowserToken(element: Element, attribute: string): string | undefined;
|
|
838
|
+
|
|
781
839
|
/**
|
|
782
840
|
* Moves a tree walker past the subtree of its current node.
|
|
783
841
|
*
|