@oya-ai/browser 1.0.97 → 1.0.101
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/dist/index.cjs +516 -326
- package/dist/index.d.cts +834 -434
- package/dist/index.d.ts +834 -434
- package/dist/index.js +518 -328
- package/package.json +14 -6
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,262 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Types for browsers themselves: starting one, what a page looks like to the
|
|
3
|
+
* SDK, the results of CAPTCHA and MFA handling, and the fleet listing.
|
|
4
|
+
*/
|
|
5
|
+
/** Where a browser comes from. Configuration, not something a caller must know. */
|
|
6
|
+
type Provider = 'oya-cloud' | 'oya-selfhosted' | 'browseruse' | 'browserbase' | 'steel' | 'anchor' | 'cdp';
|
|
7
|
+
/** How `oya.browser.start()` should start a browser. Every field is optional. */
|
|
8
|
+
interface StartOptions {
|
|
9
|
+
/** Reuse this value when retrying the same logical creation. */
|
|
10
|
+
idempotencyKey?: string;
|
|
11
|
+
/** Wait for capacity for up to five minutes; zero rejects immediately. */
|
|
12
|
+
queueMs?: number;
|
|
13
|
+
/** Spend ceiling for this browser, in US dollars. */
|
|
14
|
+
budgetUsd?: number;
|
|
15
|
+
/** Run under the project's governance: policies, budgets and recordings. */
|
|
16
|
+
governed?: boolean;
|
|
17
|
+
/** Egress and recording rules for a governed browser. */
|
|
18
|
+
policy?: {
|
|
19
|
+
/** Hosts the browser may reach; everything else is blocked. */
|
|
20
|
+
allowedHosts?: string[];
|
|
21
|
+
/** Hosts where a person, not the agent, must act. */
|
|
22
|
+
humanHosts?: string[];
|
|
23
|
+
/** Where the browser must run. */
|
|
24
|
+
region?: string;
|
|
25
|
+
/** Blur typed values out of the session recording. */
|
|
26
|
+
redactRecording?: boolean;
|
|
27
|
+
};
|
|
28
|
+
/** Place in the queue when capacity is short. */
|
|
29
|
+
priority?: 'low' | 'normal' | 'high';
|
|
30
|
+
/** Saved login profile. Defaults to the desktop's default profile. */
|
|
31
|
+
profile?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Which identity to run as. A persona is one device: fingerprint, cookie jar
|
|
34
|
+
* and proxy bound together and stable for its life.
|
|
35
|
+
* 'default' — this key's own persona (the default)
|
|
36
|
+
* 'auto' — the least recently used persona under its concurrency cap
|
|
37
|
+
* <id> — a specific persona
|
|
38
|
+
*/
|
|
39
|
+
persona?: 'default' | 'auto' | (string & {});
|
|
40
|
+
/** Solve CAPTCHAs as they appear rather than waiting to be asked. */
|
|
41
|
+
captcha?: 'auto' | 'off';
|
|
42
|
+
/** Override the key's configured provider for this browser only. */
|
|
43
|
+
provider?: Provider;
|
|
44
|
+
/** Required only for the 'cdp' provider. */
|
|
45
|
+
wsUrl?: string;
|
|
46
|
+
/** A label for the fleet listing. */
|
|
47
|
+
name?: string;
|
|
48
|
+
/** How long to wait for a cloud browser to dial in. Default 120s. */
|
|
49
|
+
readyTimeoutMs?: number;
|
|
50
|
+
}
|
|
51
|
+
/** What the server answers when a browser starts. */
|
|
52
|
+
interface StartResult {
|
|
53
|
+
/** The browser's id, for every later call. */
|
|
54
|
+
id: string;
|
|
55
|
+
/** Which provider runs it. */
|
|
56
|
+
provider: string;
|
|
57
|
+
/** Which persona it runs as. */
|
|
58
|
+
persona: string;
|
|
59
|
+
/** 'starting' while a cloud browser has yet to dial in. */
|
|
60
|
+
status: 'ready' | 'starting';
|
|
61
|
+
/** Point Playwright, Puppeteer or browser-use at this. */
|
|
62
|
+
cdpUrl?: string;
|
|
63
|
+
/** Anything the server wants the caller to know about this start. */
|
|
64
|
+
note?: string;
|
|
65
|
+
}
|
|
66
|
+
/** One element on the page, numbered by `analyze()`. */
|
|
67
|
+
interface Element {
|
|
68
|
+
/** The number to pass to `click()` and `type()`. Valid until the page changes. */
|
|
69
|
+
id: number;
|
|
70
|
+
/** What kind of control it is: link, button, input and so on. */
|
|
71
|
+
type: string;
|
|
72
|
+
/** Visible label, capped at 80 characters by the analyzer. */
|
|
73
|
+
text?: string;
|
|
74
|
+
/** Where a link goes. */
|
|
75
|
+
href?: string;
|
|
76
|
+
/** The current value of a field. */
|
|
77
|
+
value?: string;
|
|
78
|
+
/** Whether a checkbox or radio is ticked. */
|
|
79
|
+
checked?: boolean;
|
|
80
|
+
/** Whether it refuses input. */
|
|
81
|
+
disabled?: boolean;
|
|
82
|
+
/** Whether it is on screen. */
|
|
83
|
+
visible: boolean;
|
|
84
|
+
/** The HTML tag name. */
|
|
85
|
+
tag?: string;
|
|
86
|
+
/** The element's DOM `id`. Usually the most stable handle a site offers. */
|
|
87
|
+
domId?: string;
|
|
88
|
+
/** Its `aria-label`. */
|
|
89
|
+
ariaLabel?: string;
|
|
90
|
+
/** `data-testid`, when the site ships one. */
|
|
91
|
+
testId?: string;
|
|
92
|
+
/** Its `name` attribute. */
|
|
93
|
+
name?: string;
|
|
94
|
+
/** A field's placeholder text. */
|
|
95
|
+
placeholder?: string;
|
|
96
|
+
/** Action of the enclosing form. */
|
|
97
|
+
formName?: string;
|
|
98
|
+
}
|
|
99
|
+
/** How `analyze()` writes the page: markdown (the default) or toon (toonformat.dev). */
|
|
100
|
+
type PageFormat = 'markdown' | 'toon' | 'jsonl';
|
|
101
|
+
/** What `analyze()` accepts. */
|
|
102
|
+
interface AnalyzeOptions {
|
|
103
|
+
/** How the page is written: markdown (the default) or toon. */
|
|
104
|
+
format?: PageFormat;
|
|
105
|
+
}
|
|
106
|
+
/** One block of a page, in reading order: a heading, paragraph, list item, table row, image or element. */
|
|
107
|
+
interface Block {
|
|
108
|
+
/** The element's id, for interactive elements; act on it with click and type. */
|
|
109
|
+
id?: number;
|
|
110
|
+
/** The part of the page it is in: nav, main, form/…, dialog, or empty. */
|
|
111
|
+
region: string;
|
|
112
|
+
/** What it is: h1-h6, text, item, row, header, quote, code, image, or an element kind (link, button, input:email…). */
|
|
113
|
+
kind: string;
|
|
114
|
+
/** Its text, or an element's name. */
|
|
115
|
+
text?: string;
|
|
116
|
+
/** Where a link goes, or what a field holds now. */
|
|
117
|
+
target?: string;
|
|
118
|
+
/** An element's state: checked, disabled, required, off-screen, hint… */
|
|
119
|
+
state?: string;
|
|
120
|
+
}
|
|
121
|
+
/** The page as `analyze()` sees it. */
|
|
122
|
+
interface Analysis {
|
|
123
|
+
/** The format `page` is written in. */
|
|
124
|
+
format?: PageFormat;
|
|
125
|
+
/** The page, written in `format`. */
|
|
126
|
+
page?: string;
|
|
127
|
+
/** The page as markdown; present when the format is markdown (the default). */
|
|
128
|
+
markdown?: string;
|
|
129
|
+
/** The page's facts: url, title, scroll, and when they apply panelScroll, modal, covered, truncated. */
|
|
130
|
+
facts?: Record<string, string | number>;
|
|
131
|
+
/** The page as data: every block in reading order, whatever the format. */
|
|
132
|
+
blocks?: Block[];
|
|
133
|
+
/** Every numbered element, visible or not. */
|
|
134
|
+
elements: Element[];
|
|
135
|
+
/** The window size, in CSS pixels. */
|
|
136
|
+
viewport?: {
|
|
137
|
+
/** Width in CSS pixels. */
|
|
138
|
+
width: number;
|
|
139
|
+
/** Height in CSS pixels. */
|
|
140
|
+
height: number;
|
|
141
|
+
};
|
|
142
|
+
/** How far the page is scrolled. */
|
|
143
|
+
scroll?: {
|
|
144
|
+
/** Horizontal offset in CSS pixels. */
|
|
145
|
+
x: number;
|
|
146
|
+
/** Vertical offset in CSS pixels. */
|
|
147
|
+
y: number;
|
|
148
|
+
};
|
|
149
|
+
/** True when the page was too long to send in full. */
|
|
150
|
+
truncated?: boolean;
|
|
151
|
+
}
|
|
152
|
+
/** What `solveCaptcha()` found and did. */
|
|
153
|
+
interface CaptchaResult {
|
|
154
|
+
/** Whether a CAPTCHA was on the page. */
|
|
155
|
+
present: boolean;
|
|
156
|
+
/** Whether it was cleared. */
|
|
157
|
+
solved: boolean;
|
|
158
|
+
/** 'provider' when the vendor solved it, 'solver' when we did, 'none' otherwise. */
|
|
159
|
+
method: 'provider' | 'solver' | 'none';
|
|
160
|
+
/** Which kind of CAPTCHA it was. */
|
|
161
|
+
type?: string;
|
|
162
|
+
/** Invisible reCAPTCHA v3 scores the visit passively; there is nothing on screen to clear. */
|
|
163
|
+
invisible?: boolean;
|
|
164
|
+
/** The site key the solver was given. */
|
|
165
|
+
sitekey?: string | null;
|
|
166
|
+
/** Why it was not solved. */
|
|
167
|
+
error?: string;
|
|
168
|
+
}
|
|
169
|
+
/** What `completeMfa()` found and did. */
|
|
170
|
+
interface MfaResult {
|
|
171
|
+
/** Whether an MFA prompt was on the page. */
|
|
172
|
+
present: boolean;
|
|
173
|
+
/** Whether it was answered and accepted. */
|
|
174
|
+
completed: boolean;
|
|
175
|
+
/** Which factor answered it, or 'handoff' when a person must. */
|
|
176
|
+
method?: 'totp' | 'email' | 'sms' | 'handoff' | 'none';
|
|
177
|
+
/** Whether the code was typed in. */
|
|
178
|
+
filled?: boolean;
|
|
179
|
+
/** Whether the form was submitted. */
|
|
180
|
+
submitted?: boolean;
|
|
181
|
+
/** Open this to finish by hand when nothing automated can. */
|
|
182
|
+
liveViewUrl?: string | null;
|
|
183
|
+
/** Why it could not be completed. */
|
|
184
|
+
error?: string;
|
|
185
|
+
}
|
|
186
|
+
/** How a browser is doing, judged from its recent commands and heartbeats. */
|
|
187
|
+
type Health = 'ok' | 'stale' | 'errors' | 'dead';
|
|
188
|
+
/** One thing a browser did. */
|
|
189
|
+
interface Activity {
|
|
190
|
+
/** When, as an ISO timestamp. */
|
|
191
|
+
ts: string;
|
|
192
|
+
/** The command's name. */
|
|
193
|
+
action: string;
|
|
194
|
+
/** A one-line account of it. */
|
|
195
|
+
summary: string;
|
|
196
|
+
/** Whether it succeeded. */
|
|
197
|
+
ok: boolean;
|
|
198
|
+
/** How long it took. */
|
|
199
|
+
ms: number;
|
|
200
|
+
/** Why it failed. */
|
|
201
|
+
error?: string;
|
|
202
|
+
}
|
|
203
|
+
/** The outcome of stopping one browser. */
|
|
204
|
+
interface StopResult {
|
|
205
|
+
/** The browser. */
|
|
206
|
+
id: string;
|
|
207
|
+
/** Whether it stopped. */
|
|
208
|
+
ok: boolean;
|
|
209
|
+
/** Which provider ran it. */
|
|
210
|
+
provider?: string | null;
|
|
211
|
+
/** For a cloud browser, whether its sandbox was destroyed (and billing ended). */
|
|
212
|
+
sandboxRemoved?: boolean | null;
|
|
213
|
+
/** Why it did not stop. */
|
|
214
|
+
error?: string;
|
|
215
|
+
}
|
|
216
|
+
/** One browser in the fleet listing. */
|
|
217
|
+
interface BrowserInfo {
|
|
218
|
+
/** The browser's id. */
|
|
219
|
+
id: string;
|
|
220
|
+
/** Its label. */
|
|
221
|
+
name: string;
|
|
222
|
+
/** An Oya Browser on the control socket, or a third-party browser over CDP. */
|
|
223
|
+
clientType: 'oya' | 'cdp';
|
|
224
|
+
/** Which provider runs it. */
|
|
225
|
+
provider: string | null;
|
|
226
|
+
/** The persona id it runs as. */
|
|
227
|
+
persona: string | null;
|
|
228
|
+
/** That persona's name. */
|
|
229
|
+
personaName: string | null;
|
|
230
|
+
/** How it is doing. */
|
|
231
|
+
health: Health;
|
|
232
|
+
/** When it connected. */
|
|
233
|
+
connectedAt: string;
|
|
234
|
+
/** When it was last heard from. */
|
|
235
|
+
lastSeen: string;
|
|
236
|
+
/** The page it is on. */
|
|
237
|
+
currentUrl: string;
|
|
238
|
+
/** Commands run so far. */
|
|
239
|
+
commands: number;
|
|
240
|
+
/** Commands that failed. */
|
|
241
|
+
errors: number;
|
|
242
|
+
/** Commands in flight. */
|
|
243
|
+
pending: number;
|
|
244
|
+
/** When it last ran a command. */
|
|
245
|
+
lastCommandAt: string | null;
|
|
246
|
+
/** The last failure's message. */
|
|
247
|
+
lastError: string | null;
|
|
248
|
+
}
|
|
249
|
+
/** A browser plus what it has been doing, from `browser.status()`. */
|
|
250
|
+
interface BrowserDetail extends BrowserInfo {
|
|
251
|
+
/** Its most recent commands, newest first. */
|
|
252
|
+
activity: Activity[];
|
|
9
253
|
}
|
|
10
254
|
|
|
11
|
-
/**
|
|
255
|
+
/**
|
|
256
|
+
* Types for a key's settings: the LLM behind `ask()`, the browser provider and
|
|
257
|
+
* the CAPTCHA solver, as `config.set()` accepts them and `config.get()` returns them.
|
|
258
|
+
*/
|
|
259
|
+
|
|
12
260
|
/** Which model drives `ask()` and the chat API. */
|
|
13
261
|
type LlmProvider = 'openai' | 'anthropic'
|
|
14
262
|
/** Gemini via AI Studio. */
|
|
@@ -24,6 +272,7 @@ type CaptchaSolver = 'capsolver' | '2captcha' | '';
|
|
|
24
272
|
* `null` clears a field and falls back to the deployment default.
|
|
25
273
|
*/
|
|
26
274
|
interface ConfigUpdate {
|
|
275
|
+
/** Which LLM vendor `ask()` and the chat API call. */
|
|
27
276
|
llm_provider?: LlmProvider | null;
|
|
28
277
|
/** The credential for whichever `llm_provider` is set — the field name is shared. */
|
|
29
278
|
openai_api_key?: string | null;
|
|
@@ -31,111 +280,119 @@ interface ConfigUpdate {
|
|
|
31
280
|
openai_base_url?: string | null;
|
|
32
281
|
/** Overrides the provider's default model. */
|
|
33
282
|
chat_model?: string | null;
|
|
283
|
+
/** Where this key's browsers run unless `start()` names a provider. */
|
|
34
284
|
browser_provider?: Provider | null;
|
|
285
|
+
/** Anchor's API key, for the 'anchor' provider. */
|
|
35
286
|
anchor_api_key?: string | null;
|
|
287
|
+
/** Browserbase's API key, for the 'browserbase' provider. */
|
|
36
288
|
browserbase_api_key?: string | null;
|
|
289
|
+
/** The Browserbase project browsers are created in. */
|
|
37
290
|
browserbase_project_id?: string | null;
|
|
291
|
+
/** Steel's API key, for the 'steel' provider. */
|
|
38
292
|
steel_api_key?: string | null;
|
|
293
|
+
/** Browser Use Cloud's API key, for the 'browseruse' provider. */
|
|
39
294
|
browseruse_api_key?: string | null;
|
|
295
|
+
/** The DevTools WebSocket URL of your own Chrome, for the 'cdp' provider. */
|
|
40
296
|
cdp_ws_url?: string | null;
|
|
297
|
+
/** Which CAPTCHA solving service to call. */
|
|
41
298
|
captcha_solver?: CaptchaSolver | null;
|
|
299
|
+
/** The solving service's API key. */
|
|
42
300
|
captcha_api_key?: string | null;
|
|
301
|
+
/** Set once onboarding has been completed, so the console stops offering it. */
|
|
43
302
|
onboarded?: string | null;
|
|
44
303
|
}
|
|
45
304
|
/** What `config.get()` returns. Secrets read back masked, never in full. */
|
|
46
305
|
interface Config extends Omit<ConfigUpdate, 'llm_provider' | 'browser_provider' | 'captcha_solver'> {
|
|
306
|
+
/** The configured LLM vendor, or empty for the deployment default. */
|
|
47
307
|
llm_provider?: LlmProvider | '';
|
|
308
|
+
/** The configured browser provider, or empty for the deployment default. */
|
|
48
309
|
browser_provider?: Provider | '';
|
|
310
|
+
/** The configured CAPTCHA solver; empty when solving is off. */
|
|
49
311
|
captcha_solver?: CaptchaSolver;
|
|
50
312
|
/** What this key would actually use right now, deployment defaults included. */
|
|
51
313
|
effective: {
|
|
314
|
+
/** The LLM endpoint in use. */
|
|
52
315
|
baseUrl: string;
|
|
316
|
+
/** The model in use. */
|
|
53
317
|
model: string;
|
|
318
|
+
/** Whether any LLM credential is available. */
|
|
54
319
|
hasLlmKey: boolean;
|
|
55
320
|
};
|
|
56
321
|
/** True when the LLM key in play belongs to the deployment, not this key. */
|
|
57
322
|
inherited: boolean;
|
|
323
|
+
/** Whether this key has its own LLM credential stored. */
|
|
58
324
|
has_openai_key: boolean;
|
|
325
|
+
/** Every browser provider, what it needs configured, and whether it is. */
|
|
59
326
|
providers: Array<{
|
|
327
|
+
/** The provider. */
|
|
60
328
|
id: Provider;
|
|
329
|
+
/** Its display name. */
|
|
61
330
|
label: string;
|
|
331
|
+
/** The config fields it requires. */
|
|
62
332
|
needs: string[];
|
|
333
|
+
/** Whether those fields are set. */
|
|
63
334
|
configured: boolean;
|
|
64
335
|
}>;
|
|
65
336
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
redactRecording?: boolean;
|
|
80
|
-
};
|
|
81
|
-
priority?: 'low' | 'normal' | 'high';
|
|
82
|
-
/** Saved login profile. Defaults to the desktop's default profile. */
|
|
83
|
-
profile?: string;
|
|
84
|
-
/**
|
|
85
|
-
* Which identity to run as. A persona is one device: fingerprint, cookie jar
|
|
86
|
-
* and proxy bound together and stable for its life.
|
|
87
|
-
* 'default' — this key's own persona (the default)
|
|
88
|
-
* 'auto' — the least recently used persona under its concurrency cap
|
|
89
|
-
* <id> — a specific persona
|
|
90
|
-
*/
|
|
91
|
-
persona?: 'default' | 'auto' | (string & {});
|
|
92
|
-
/** Solve CAPTCHAs as they appear rather than waiting to be asked. */
|
|
93
|
-
captcha?: 'auto' | 'off';
|
|
94
|
-
/** Override the key's configured provider for this browser only. */
|
|
95
|
-
provider?: Provider;
|
|
96
|
-
/** Required only for the 'cdp' provider. */
|
|
97
|
-
wsUrl?: string;
|
|
98
|
-
name?: string;
|
|
99
|
-
/** How long to wait for a cloud browser to dial in. Default 120s. */
|
|
100
|
-
readyTimeoutMs?: number;
|
|
101
|
-
}
|
|
102
|
-
interface StartResult {
|
|
103
|
-
id: string;
|
|
104
|
-
provider: string;
|
|
105
|
-
persona: string;
|
|
106
|
-
status: 'ready' | 'starting';
|
|
107
|
-
/** Point Playwright, Puppeteer or browser-use at this. */
|
|
108
|
-
cdpUrl?: string;
|
|
109
|
-
note?: string;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* OyaError: the one error type the SDK throws for a failed call, carrying the
|
|
340
|
+
* HTTP status and the server's answer so a caller can branch on either.
|
|
341
|
+
*/
|
|
342
|
+
/** A failed API call or browser command. */
|
|
343
|
+
declare class OyaError extends Error {
|
|
344
|
+
/** The HTTP status, or the SDK's own status for errors it raises itself. */
|
|
345
|
+
readonly status: number;
|
|
346
|
+
/** The server's response body, parsed when it was JSON. */
|
|
347
|
+
readonly body: unknown;
|
|
348
|
+
/** Records the message, status and body. */
|
|
349
|
+
constructor(message: string, status: number, body: unknown);
|
|
110
350
|
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Types for agent work: task values and files, playbooks and their replays,
|
|
354
|
+
* and background runs with their attention requests.
|
|
355
|
+
*/
|
|
356
|
+
|
|
357
|
+
/** A saved flow, replayable without an LLM. */
|
|
111
358
|
interface Playbook {
|
|
359
|
+
/** The name it is played by. */
|
|
112
360
|
name: string;
|
|
113
361
|
/** Inputs `play()` accepts; any left out reuse the recorded value. */
|
|
114
362
|
variables: string[];
|
|
115
363
|
/** What each variable was recorded with. A secret has none — it never left the page. */
|
|
116
364
|
defaults: Record<string, string>;
|
|
365
|
+
/** How many steps it replays. */
|
|
117
366
|
steps: number;
|
|
118
367
|
/** The same flow as a Playwright module: `export default async function run(page, vars)`. */
|
|
119
368
|
code: string;
|
|
120
369
|
}
|
|
370
|
+
/** What a `play()` did. */
|
|
121
371
|
interface PlayResult {
|
|
122
372
|
/** Steps replayed before finishing or handing over to the agent. */
|
|
123
373
|
steps: number;
|
|
374
|
+
/** Steps in the playbook. */
|
|
124
375
|
total: number;
|
|
125
376
|
/** A step no longer fit the page and the agent finished the task. */
|
|
126
377
|
fellBack: boolean;
|
|
127
378
|
/** The agent's fix was saved as `draft`; promote it with `oya.playbooks.promote(name)`. */
|
|
128
379
|
healed?: boolean;
|
|
380
|
+
/** The draft's name, when one was saved. */
|
|
129
381
|
draft?: string;
|
|
130
382
|
/** The agent's summary, when it fell back. */
|
|
131
383
|
text?: string;
|
|
132
384
|
}
|
|
385
|
+
/** A playbook in the listing, with its history and any pending fix. */
|
|
133
386
|
interface PlaybookSummary extends Playbook {
|
|
387
|
+
/** When it was saved. */
|
|
134
388
|
createdAt: string | null;
|
|
389
|
+
/** When a draft last replaced it. */
|
|
135
390
|
promotedAt: string | null;
|
|
136
391
|
/** A healed replay's fix, waiting for `promote()` or `remove('<name>:draft')`. */
|
|
137
392
|
draft: (Playbook & {
|
|
393
|
+
/** When the replay was healed. */
|
|
138
394
|
healedAt: string;
|
|
395
|
+
/** The step the replay broke at. */
|
|
139
396
|
healedFrom: number;
|
|
140
397
|
}) | null;
|
|
141
398
|
}
|
|
@@ -161,29 +418,46 @@ interface FileValue {
|
|
|
161
418
|
* upload tool rather than typing it.
|
|
162
419
|
*/
|
|
163
420
|
type RunData = Record<string, string | number | FileValue>;
|
|
421
|
+
/** A run is waiting on a person. */
|
|
164
422
|
interface AttentionRequest {
|
|
423
|
+
/** Identifies this request; a new one means a new problem. */
|
|
165
424
|
id: string;
|
|
166
425
|
/** captcha / login / mfa: finish it in the live view. agent: the agent's question. heal_failed: replay and the agent both gave up. */
|
|
167
426
|
reason: 'captcha' | 'login' | 'mfa' | 'agent' | 'heal_failed';
|
|
427
|
+
/** What is needed, in words. */
|
|
168
428
|
message: string;
|
|
429
|
+
/** Where to finish it by hand. */
|
|
169
430
|
liveViewUrl?: string;
|
|
431
|
+
/** When it was raised, in epoch milliseconds. */
|
|
170
432
|
at: number;
|
|
171
433
|
}
|
|
434
|
+
/** What a finished run produced: a replay's result, an agent's answer, or both. */
|
|
172
435
|
type RunResult = Partial<PlayResult> & {
|
|
436
|
+
/** The agent's answer. */
|
|
173
437
|
text?: string;
|
|
174
438
|
};
|
|
439
|
+
/** A background run's state. */
|
|
175
440
|
interface RunInfo {
|
|
441
|
+
/** The run's id. */
|
|
176
442
|
id: string;
|
|
443
|
+
/** The browser it runs on. */
|
|
177
444
|
browserId: string;
|
|
445
|
+
/** Where it is. */
|
|
178
446
|
status: 'running' | 'needs_attention' | 'succeeded' | 'failed';
|
|
447
|
+
/** When it started, in epoch milliseconds. */
|
|
179
448
|
createdAt: number;
|
|
449
|
+
/** When it ended. */
|
|
180
450
|
endedAt?: number;
|
|
451
|
+
/** The open request for a person, if any. */
|
|
181
452
|
attention: AttentionRequest | null;
|
|
453
|
+
/** What it produced, once it succeeded. */
|
|
182
454
|
result?: RunResult;
|
|
455
|
+
/** Why it failed. */
|
|
183
456
|
error?: string;
|
|
184
457
|
/** HTTP-style status of a failure: 429 when a quota stopped the run. */
|
|
185
458
|
errorStatus?: number;
|
|
186
459
|
}
|
|
460
|
+
/** The inputs and callbacks for `browser.submit()`. */
|
|
187
461
|
interface SubmitOptions {
|
|
188
462
|
/** Task values the agent can read; for a playbook, its variables (secret ones included). */
|
|
189
463
|
data?: RunData;
|
|
@@ -191,7 +465,9 @@ interface SubmitOptions {
|
|
|
191
465
|
secrets?: RunData;
|
|
192
466
|
/** Playbooks only: let the agent finish a broken replay and save its fix as a draft. Default true. */
|
|
193
467
|
autoHeal?: boolean;
|
|
468
|
+
/** Fires once with the result when the run succeeds. */
|
|
194
469
|
onSuccess?: (result: RunResult) => unknown;
|
|
470
|
+
/** Fires once when the run fails, or when it can no longer be polled. */
|
|
195
471
|
onFailure?: (error: OyaError) => unknown;
|
|
196
472
|
/** Call `respond()` once it is handled: `'done'` after finishing by hand, or your answer to the agent. */
|
|
197
473
|
onHumanAttention?: (request: AttentionRequest & {
|
|
@@ -202,165 +478,151 @@ interface SubmitOptions {
|
|
|
202
478
|
/** How often to check on the run. Default 2000. */
|
|
203
479
|
pollMs?: number;
|
|
204
480
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
value?: string;
|
|
212
|
-
checked?: boolean;
|
|
213
|
-
disabled?: boolean;
|
|
214
|
-
visible: boolean;
|
|
215
|
-
tag?: string;
|
|
216
|
-
/** The element's DOM `id`. Usually the most stable handle a site offers. */
|
|
217
|
-
domId?: string;
|
|
218
|
-
ariaLabel?: string;
|
|
219
|
-
/** `data-testid`, when the site ships one. */
|
|
220
|
-
testId?: string;
|
|
221
|
-
name?: string;
|
|
222
|
-
placeholder?: string;
|
|
223
|
-
/** Action of the enclosing form. */
|
|
224
|
-
formName?: string;
|
|
225
|
-
}
|
|
226
|
-
interface Analysis {
|
|
227
|
-
/** The page as markdown. */
|
|
228
|
-
markdown: string;
|
|
229
|
-
elements: Element[];
|
|
230
|
-
viewport?: {
|
|
231
|
-
width: number;
|
|
232
|
-
height: number;
|
|
233
|
-
};
|
|
234
|
-
scroll?: {
|
|
235
|
-
x: number;
|
|
236
|
-
y: number;
|
|
237
|
-
};
|
|
238
|
-
truncated?: boolean;
|
|
239
|
-
}
|
|
240
|
-
interface CaptchaResult {
|
|
241
|
-
present: boolean;
|
|
242
|
-
solved: boolean;
|
|
243
|
-
/** 'provider' when the vendor solved it, 'solver' when we did, 'none' otherwise. */
|
|
244
|
-
method: 'provider' | 'solver' | 'none';
|
|
245
|
-
type?: string;
|
|
246
|
-
/** Invisible reCAPTCHA v3 scores the visit passively; there is nothing on screen to clear. */
|
|
247
|
-
invisible?: boolean;
|
|
248
|
-
sitekey?: string | null;
|
|
249
|
-
error?: string;
|
|
250
|
-
}
|
|
251
|
-
interface MfaResult {
|
|
252
|
-
present: boolean;
|
|
253
|
-
completed: boolean;
|
|
254
|
-
method?: 'totp' | 'email' | 'sms' | 'handoff' | 'none';
|
|
255
|
-
filled?: boolean;
|
|
256
|
-
submitted?: boolean;
|
|
257
|
-
/** Open this to finish by hand when nothing automated can. */
|
|
258
|
-
liveViewUrl?: string | null;
|
|
259
|
-
error?: string;
|
|
260
|
-
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Types for identities: a persona's device and fingerprint, the proxies it
|
|
484
|
+
* exits through, and the second factors and site logins stored for it.
|
|
485
|
+
*/
|
|
486
|
+
/** The device a persona presents. Fixed for its life. */
|
|
261
487
|
interface Fingerprint {
|
|
488
|
+
/** `navigator.platform`. */
|
|
262
489
|
platform: string;
|
|
490
|
+
/** IANA timezone. */
|
|
263
491
|
timezone: string;
|
|
492
|
+
/** BCP 47 locale. */
|
|
264
493
|
locale: string;
|
|
494
|
+
/** Screen size, as `WIDTHxHEIGHT`. */
|
|
265
495
|
screen: string;
|
|
496
|
+
/** The GPU the WebGL renderer reports. */
|
|
266
497
|
webgl: string;
|
|
498
|
+
/** Logical CPU cores reported. */
|
|
267
499
|
hardwareConcurrency: number;
|
|
500
|
+
/** Device memory reported, in GB. */
|
|
268
501
|
deviceMemory: number;
|
|
502
|
+
/** Seed for the persona's stable canvas noise. */
|
|
269
503
|
canvasSeed: number;
|
|
270
504
|
}
|
|
271
505
|
/** Device choices made at creation. Fixed for the persona's life. */
|
|
272
506
|
interface PersonaPrefs {
|
|
507
|
+
/** Which operating system to present. */
|
|
273
508
|
platform?: 'Win32' | 'MacIntel' | 'Linux x86_64';
|
|
509
|
+
/** IANA timezone; must be one the platform can coherently claim. */
|
|
274
510
|
timezone?: string;
|
|
511
|
+
/** BCP 47 locale; must be one the platform can coherently claim. */
|
|
275
512
|
locale?: string;
|
|
276
513
|
}
|
|
277
514
|
/** A proxy exit. Credentials go in on create and never come back out. */
|
|
278
515
|
interface ProxyInfo {
|
|
516
|
+
/** The proxy's id. */
|
|
279
517
|
id: string;
|
|
518
|
+
/** Its display name. */
|
|
280
519
|
label: string;
|
|
520
|
+
/** Residential IPs look like homes; datacenter ones are cheaper and easier to flag. */
|
|
281
521
|
kind: 'residential' | 'datacenter';
|
|
282
522
|
/** Two-letter country, optionally a region: "US", "US-CA". */
|
|
283
523
|
geo: string | null;
|
|
284
524
|
/** Provided by the host rather than this key. Cannot be removed. */
|
|
285
525
|
shared: boolean;
|
|
526
|
+
/** Whether its last check passed. */
|
|
286
527
|
healthy: boolean;
|
|
287
528
|
/** Healthy and not cooling down after a failure. */
|
|
288
529
|
available: boolean;
|
|
289
530
|
/** Where traffic actually leaves, as of the last check. */
|
|
290
531
|
exitIp: string | null;
|
|
532
|
+
/** When it was last checked. */
|
|
291
533
|
lastCheckedAt: string | null;
|
|
292
534
|
/** Personas on it now, out of `maxPersonas`. */
|
|
293
535
|
assigned: number;
|
|
536
|
+
/** How many personas may share it. */
|
|
294
537
|
maxPersonas: number;
|
|
538
|
+
/** How long until a failed proxy is tried again. */
|
|
295
539
|
cooldownMsRemaining: number;
|
|
296
540
|
}
|
|
541
|
+
/** A proxy to add. */
|
|
297
542
|
interface ProxyCreate {
|
|
298
543
|
/** http(s)://user:pass@host:port from your vendor. Chromium cannot use SOCKS5 with a password. */
|
|
299
544
|
url: string;
|
|
545
|
+
/** A display name. */
|
|
300
546
|
label?: string;
|
|
547
|
+
/** Two-letter country, optionally a region, used to match personas' geo hints. */
|
|
301
548
|
geo?: string;
|
|
549
|
+
/** Residential or datacenter. */
|
|
302
550
|
kind?: 'residential' | 'datacenter';
|
|
303
551
|
/** Personas that may share it. Keep 1 for a sticky-session URL so each keeps its own IP. */
|
|
304
552
|
maxPersonas?: number;
|
|
305
553
|
}
|
|
554
|
+
/** A persona: one device, its cookie jar and its proxy. */
|
|
306
555
|
interface PersonaInfo {
|
|
556
|
+
/** The persona's id. */
|
|
307
557
|
id: string;
|
|
558
|
+
/** Its display name. */
|
|
308
559
|
name: string;
|
|
560
|
+
/** Whether it is this key's own default persona. */
|
|
309
561
|
isDefault: boolean;
|
|
562
|
+
/** Browsers running as it now. */
|
|
310
563
|
activeBrowsers: number;
|
|
564
|
+
/** How many may run as it at once; null for no cap. */
|
|
311
565
|
maxConcurrent: number | null;
|
|
566
|
+
/** Where its proxy should be, before one is assigned. */
|
|
312
567
|
proxy: {
|
|
568
|
+
/** Two-letter country, optionally a region. */
|
|
313
569
|
geo: string | null;
|
|
314
570
|
} | null;
|
|
315
571
|
/** The proxy it is actually on, once assigned or pinned. */
|
|
316
572
|
exit: {
|
|
573
|
+
/** The proxy's id. */
|
|
317
574
|
id: string;
|
|
575
|
+
/** Its display name. */
|
|
318
576
|
label: string;
|
|
577
|
+
/** Its country and region. */
|
|
319
578
|
geo: string | null;
|
|
579
|
+
/** Whether its last check passed. */
|
|
320
580
|
healthy: boolean;
|
|
321
581
|
} | null;
|
|
582
|
+
/** The device choices it was created with. */
|
|
322
583
|
prefs: PersonaPrefs | null;
|
|
584
|
+
/** The device it presents. */
|
|
323
585
|
fingerprint: Fingerprint;
|
|
586
|
+
/** Its persona-wide second factor. */
|
|
324
587
|
mfa: {
|
|
588
|
+
/** Whether a factor is stored. */
|
|
325
589
|
configured: boolean;
|
|
590
|
+
/** Which kind of factor. */
|
|
326
591
|
type?: string;
|
|
592
|
+
/** The site it is filed against, if any. */
|
|
327
593
|
domain?: string;
|
|
328
594
|
};
|
|
329
595
|
/** Per-site factors and stored logins. Usernames and types only, never secrets. */
|
|
330
596
|
sites: {
|
|
597
|
+
/** Second factors filed against one site. */
|
|
331
598
|
mfa: {
|
|
599
|
+
/** The site. */
|
|
332
600
|
domain: string;
|
|
601
|
+
/** Which kind of factor. */
|
|
333
602
|
type: string;
|
|
334
603
|
}[];
|
|
604
|
+
/** Stored site logins. */
|
|
335
605
|
credentials: {
|
|
606
|
+
/** The site. */
|
|
336
607
|
domain: string;
|
|
608
|
+
/** The account name. */
|
|
337
609
|
username: string;
|
|
338
610
|
}[];
|
|
339
611
|
};
|
|
612
|
+
/** What its cookie jar holds. */
|
|
340
613
|
login: {
|
|
614
|
+
/** Cookies in the jar. */
|
|
341
615
|
cookies: number;
|
|
616
|
+
/** Sites it holds a session for. */
|
|
342
617
|
sites: string[];
|
|
618
|
+
/** When the jar last changed. */
|
|
343
619
|
updatedAt: string | null;
|
|
344
620
|
};
|
|
621
|
+
/** When it was created. */
|
|
345
622
|
createdAt: string;
|
|
623
|
+
/** When a browser last ran as it. */
|
|
346
624
|
lastUsedAt: string | null;
|
|
347
625
|
}
|
|
348
|
-
type Health = 'ok' | 'stale' | 'errors' | 'dead';
|
|
349
|
-
interface Activity {
|
|
350
|
-
ts: string;
|
|
351
|
-
action: string;
|
|
352
|
-
summary: string;
|
|
353
|
-
ok: boolean;
|
|
354
|
-
ms: number;
|
|
355
|
-
error?: string;
|
|
356
|
-
}
|
|
357
|
-
interface StopResult {
|
|
358
|
-
id: string;
|
|
359
|
-
ok: boolean;
|
|
360
|
-
provider?: string | null;
|
|
361
|
-
sandboxRemoved?: boolean | null;
|
|
362
|
-
error?: string;
|
|
363
|
-
}
|
|
364
626
|
/**
|
|
365
627
|
* A second factor. `domain` files it against one site, because a persona driving
|
|
366
628
|
* several portals meets several kinds of factor; without it the record is the
|
|
@@ -375,122 +637,452 @@ interface StopResult {
|
|
|
375
637
|
* `pattern` is only the fallback for when no LLM key is set or the call fails.
|
|
376
638
|
*/
|
|
377
639
|
type MfaConfig = {
|
|
640
|
+
/** The site this factor answers for; without it, the persona-wide default. */
|
|
378
641
|
domain?: string;
|
|
379
642
|
} & ({
|
|
643
|
+
/** An authenticator app's time-based codes. */
|
|
380
644
|
type: 'totp';
|
|
645
|
+
/** The base32 seed. */
|
|
381
646
|
secret: string;
|
|
382
647
|
} | {
|
|
648
|
+
/** Codes delivered to an endpoint you host. */
|
|
383
649
|
type: 'email' | 'sms';
|
|
650
|
+
/** The endpoint polled for the latest message. */
|
|
384
651
|
url: string;
|
|
652
|
+
/** Headers sent with each poll. */
|
|
385
653
|
headers?: Record<string, string>;
|
|
654
|
+
/** Fallback regex for the code, used when no LLM is available. */
|
|
386
655
|
pattern?: string;
|
|
656
|
+
/** How long to wait for a code. */
|
|
387
657
|
timeoutMs?: number;
|
|
388
658
|
} | {
|
|
659
|
+
/** Codes read from a Gmail or Microsoft 365 mailbox. */
|
|
389
660
|
type: 'gmail' | 'graph';
|
|
661
|
+
/** The mailbox's OAuth refresh token. */
|
|
390
662
|
refreshToken: string;
|
|
663
|
+
/** The OAuth client the token was issued to. */
|
|
391
664
|
clientId: string;
|
|
665
|
+
/** That client's secret, when it has one. */
|
|
392
666
|
clientSecret?: string;
|
|
667
|
+
/** The Microsoft tenant, for `graph`. */
|
|
393
668
|
tenant?: string;
|
|
669
|
+
/** A mailbox search narrowing which messages are read. */
|
|
394
670
|
query?: string;
|
|
671
|
+
/** Fallback regex for the code, used when no LLM is available. */
|
|
395
672
|
pattern?: string;
|
|
673
|
+
/** How long to wait for a code. */
|
|
396
674
|
timeoutMs?: number;
|
|
397
675
|
});
|
|
398
676
|
/** A site login. The password is write-only: no API ever reads it back. */
|
|
399
677
|
interface SiteCredentials {
|
|
678
|
+
/** The site it signs in to. */
|
|
400
679
|
domain: string;
|
|
680
|
+
/** The account name. */
|
|
401
681
|
username: string;
|
|
682
|
+
/** The password; stored sealed and never returned. */
|
|
402
683
|
password: string;
|
|
403
684
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
personaName: string | null;
|
|
411
|
-
health: Health;
|
|
412
|
-
connectedAt: string;
|
|
413
|
-
lastSeen: string;
|
|
414
|
-
currentUrl: string;
|
|
415
|
-
commands: number;
|
|
416
|
-
errors: number;
|
|
417
|
-
pending: number;
|
|
418
|
-
lastCommandAt: string | null;
|
|
419
|
-
lastError: string | null;
|
|
420
|
-
}
|
|
421
|
-
interface BrowserDetail extends BrowserInfo {
|
|
422
|
-
activity: Activity[];
|
|
423
|
-
}
|
|
424
|
-
interface OyaOptions {
|
|
425
|
-
/** Defaults to OYA_API_KEY. */
|
|
426
|
-
apiKey?: string;
|
|
427
|
-
/** Defaults to OYA_BASE_URL, then https://browser.getoya.ai. */
|
|
428
|
-
baseUrl?: string;
|
|
429
|
-
/** Per-request timeout. Navigation gets its own, longer budget. */
|
|
430
|
-
timeoutMs?: number;
|
|
431
|
-
fetch?: typeof globalThis.fetch;
|
|
432
|
-
}
|
|
433
|
-
declare class OyaError extends Error {
|
|
434
|
-
readonly status: number;
|
|
435
|
-
readonly body: unknown;
|
|
436
|
-
constructor(message: string, status: number, body: unknown);
|
|
437
|
-
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Types for the durable control plane: sessions and their lifecycle, human
|
|
688
|
+
* takeover, project settings, lifecycle events and service credentials.
|
|
689
|
+
*/
|
|
690
|
+
/** What a member or credential may do: read, operate browsers, or also administer the project. */
|
|
438
691
|
type ControlRole = 'viewer' | 'operator' | 'administrator';
|
|
439
692
|
/** What a human holding the control lease may send. Mirrors the server's allowlist. */
|
|
440
693
|
type HumanInputAction = 'click' | 'type' | 'press_key' | 'scroll' | 'click_coordinates' | 'double_click' | 'drag' | 'mouse_move' | 'scroll_at' | 'type_text' | 'keyboard_type' | 'navigate' | 'back' | 'forward' | 'reload' | 'screenshot' | 'analyze' | 'read_page';
|
|
694
|
+
/** A browser session as the control plane records it, including ones no longer connected. */
|
|
441
695
|
interface ControlSession {
|
|
696
|
+
/** The session's id, which is also the browser's. */
|
|
442
697
|
id: string;
|
|
698
|
+
/** The project it belongs to. */
|
|
443
699
|
project: string;
|
|
700
|
+
/** Which provider runs it. */
|
|
444
701
|
provider: string;
|
|
702
|
+
/** The persona it runs as. */
|
|
445
703
|
persona: string | null;
|
|
704
|
+
/** Where it is in its lifecycle. */
|
|
446
705
|
state: 'queued' | 'provisioning' | 'ready' | 'disconnected' | 'stopping' | 'cleanup_pending' | 'stopped' | 'failed' | 'unknown_outcome';
|
|
706
|
+
/** Whether the control plane provisioned it (and so must clean it up). */
|
|
447
707
|
managed: boolean;
|
|
708
|
+
/** When it was created, in epoch milliseconds. */
|
|
448
709
|
createdAt: number;
|
|
710
|
+
/** When its state last changed. */
|
|
449
711
|
updatedAt: number;
|
|
712
|
+
/** Estimated spend so far, in US dollars. */
|
|
450
713
|
costUsd: number;
|
|
714
|
+
/** Who is driving it. */
|
|
451
715
|
control: {
|
|
716
|
+
/** The agent, a person, or nobody while paused. */
|
|
452
717
|
mode: 'agent' | 'human' | 'paused';
|
|
718
|
+
/** When a human lease runs out. */
|
|
453
719
|
expiresAt?: number;
|
|
454
720
|
};
|
|
721
|
+
/** Why cleanup has not finished. */
|
|
455
722
|
cleanupError?: string;
|
|
456
723
|
}
|
|
724
|
+
/** A project's limits, retention and rate cards. */
|
|
457
725
|
interface ProjectSettings {
|
|
726
|
+
/** Days recordings are kept. */
|
|
458
727
|
recordingDays: number;
|
|
728
|
+
/** Days audit events are kept. */
|
|
459
729
|
auditDays: number;
|
|
730
|
+
/** Spend ceiling in US dollars; null for none. */
|
|
460
731
|
budgetUsd: number | null;
|
|
732
|
+
/** Browsers that may run at once; null for no cap. */
|
|
461
733
|
maxConcurrent: number | null;
|
|
734
|
+
/** Price per unit, by what is metered. */
|
|
462
735
|
rates: Record<string, number>;
|
|
736
|
+
/** The default policy for governed browsers. */
|
|
463
737
|
policy: Record<string, unknown>;
|
|
464
738
|
}
|
|
739
|
+
/** One durable lifecycle event. */
|
|
465
740
|
interface ControlEvent {
|
|
741
|
+
/** Increasing id, used as the read cursor. */
|
|
466
742
|
id: number;
|
|
743
|
+
/** The project it belongs to. */
|
|
467
744
|
project: string;
|
|
745
|
+
/** What happened. */
|
|
468
746
|
type: string;
|
|
747
|
+
/** The session it concerns, if any. */
|
|
469
748
|
sessionId: string | null;
|
|
749
|
+
/** When, in epoch milliseconds. */
|
|
470
750
|
at: number;
|
|
751
|
+
/** Event-specific fields. */
|
|
471
752
|
detail: Record<string, unknown>;
|
|
472
753
|
}
|
|
754
|
+
/** A service credential. Its token is shown once, at creation. */
|
|
473
755
|
interface ControlCredential {
|
|
756
|
+
/** The credential's id, for revoking it. */
|
|
474
757
|
id: string;
|
|
758
|
+
/** What it is for. */
|
|
475
759
|
label: string;
|
|
760
|
+
/** What it may do. */
|
|
476
761
|
role: ControlRole;
|
|
762
|
+
/** When it stops working; null for never. */
|
|
477
763
|
expiresAt: number | null;
|
|
764
|
+
/** When it was revoked, if it was. */
|
|
478
765
|
revokedAt: number | null;
|
|
479
766
|
}
|
|
767
|
+
/** The project at a glance: settings, sessions, recent events. */
|
|
480
768
|
interface ControlOverview {
|
|
481
769
|
/** costUsd: estimated lifetime spend, metered from rate cards. */
|
|
482
770
|
project: {
|
|
771
|
+
/** The project's id. */
|
|
483
772
|
id: string;
|
|
773
|
+
/** Its name. */
|
|
484
774
|
name: string;
|
|
775
|
+
/** Its limits and retention. */
|
|
485
776
|
settings: ProjectSettings;
|
|
777
|
+
/** Estimated lifetime spend, in US dollars. */
|
|
486
778
|
costUsd?: number;
|
|
487
779
|
};
|
|
780
|
+
/** Every session the control plane knows about. */
|
|
488
781
|
sessions: ControlSession[];
|
|
782
|
+
/** Recent lifecycle events. */
|
|
489
783
|
events: ControlEvent[];
|
|
784
|
+
/** True while the server is draining for a restart. */
|
|
490
785
|
draining: boolean;
|
|
786
|
+
/** Service credentials, for administrators. */
|
|
491
787
|
credentials?: ControlCredential[];
|
|
492
788
|
}
|
|
493
789
|
|
|
790
|
+
/**
|
|
791
|
+
* The options the `Oya` client is constructed with.
|
|
792
|
+
*/
|
|
793
|
+
/** How to reach the control plane, and as whom. */
|
|
794
|
+
interface OyaOptions {
|
|
795
|
+
/** Defaults to OYA_API_KEY. */
|
|
796
|
+
apiKey?: string;
|
|
797
|
+
/** Defaults to OYA_BASE_URL, then https://browser.getoya.ai. */
|
|
798
|
+
baseUrl?: string;
|
|
799
|
+
/** Per-request timeout. Navigation gets its own, longer budget. */
|
|
800
|
+
timeoutMs?: number;
|
|
801
|
+
/** A fetch to use instead of the global one, for tests, proxies or old runtimes. */
|
|
802
|
+
fetch?: typeof globalThis.fetch;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/** The one HTTP path. Everything else in this package is a wrapper over it. */
|
|
806
|
+
declare class Http {
|
|
807
|
+
readonly baseUrl: string;
|
|
808
|
+
readonly apiKey: string;
|
|
809
|
+
private readonly timeoutMs;
|
|
810
|
+
private readonly fetchImpl;
|
|
811
|
+
/** Stores where to call, with which key, how long to wait and which fetch to use. */
|
|
812
|
+
constructor(baseUrl: string, apiKey: string, timeoutMs: number, fetchImpl: typeof globalThis.fetch);
|
|
813
|
+
/** Sends one request and returns the parsed answer, or throws an OyaError when it failed. */
|
|
814
|
+
request<T>(method: string, path: string, body?: unknown, timeoutMs?: number, headers?: Record<string, string>): Promise<T>;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* The shapes the client's namespaces (`oya.browser`, `oya.control`,
|
|
819
|
+
* `oya.personas` …) take and return that are not part of the exported types,
|
|
820
|
+
* named so each field can say what it is.
|
|
821
|
+
*/
|
|
822
|
+
|
|
823
|
+
/** What stopping several browsers did. */
|
|
824
|
+
interface StopManyResult {
|
|
825
|
+
/** How many stopped. */
|
|
826
|
+
stopped: number;
|
|
827
|
+
/** Each browser's outcome. */
|
|
828
|
+
results: StopResult[];
|
|
829
|
+
}
|
|
830
|
+
/** A plain acknowledgement. */
|
|
831
|
+
interface Ack {
|
|
832
|
+
/** Whether it was done. */
|
|
833
|
+
ok: boolean;
|
|
834
|
+
}
|
|
835
|
+
/** A single-use live-stream ticket. */
|
|
836
|
+
interface Ticket {
|
|
837
|
+
/** The ticket. */
|
|
838
|
+
ticket: string;
|
|
839
|
+
/** Seconds until it expires. */
|
|
840
|
+
expiresIn: number;
|
|
841
|
+
}
|
|
842
|
+
/** A page of lifecycle events. */
|
|
843
|
+
interface EventPage {
|
|
844
|
+
/** Events after the cursor asked for. */
|
|
845
|
+
events: ControlEvent[];
|
|
846
|
+
/** Pass this as `after` to read on. */
|
|
847
|
+
cursor: number;
|
|
848
|
+
}
|
|
849
|
+
/** A service credential to mint. */
|
|
850
|
+
interface CredentialRequest {
|
|
851
|
+
/** What it may do. */
|
|
852
|
+
role: ControlRole;
|
|
853
|
+
/** What it is for. */
|
|
854
|
+
label?: string;
|
|
855
|
+
/** When it stops working, in epoch milliseconds. */
|
|
856
|
+
expiresAt?: number;
|
|
857
|
+
}
|
|
858
|
+
/** A new service credential, with its token: shown this once. */
|
|
859
|
+
interface NewCredential extends ControlCredential {
|
|
860
|
+
/** The secret to authenticate with. */
|
|
861
|
+
token: string;
|
|
862
|
+
}
|
|
863
|
+
/** One project member. */
|
|
864
|
+
interface Member {
|
|
865
|
+
/** The member's user id. */
|
|
866
|
+
userId: string;
|
|
867
|
+
/** What they may do. */
|
|
868
|
+
role: ControlRole;
|
|
869
|
+
}
|
|
870
|
+
/** The project's owner and members. */
|
|
871
|
+
interface MemberList {
|
|
872
|
+
/** The owner's user id. */
|
|
873
|
+
owner: string | null;
|
|
874
|
+
/** Everyone else. */
|
|
875
|
+
members: Member[];
|
|
876
|
+
}
|
|
877
|
+
/** An invitation code. */
|
|
878
|
+
interface Invite {
|
|
879
|
+
/** The code to hand to the invitee. */
|
|
880
|
+
code: string;
|
|
881
|
+
/** Seconds until it expires. */
|
|
882
|
+
expiresIn: number;
|
|
883
|
+
}
|
|
884
|
+
/** A registered webhook. */
|
|
885
|
+
interface Webhook {
|
|
886
|
+
/** Its id, for removing it. */
|
|
887
|
+
id: string;
|
|
888
|
+
/** The key its deliveries are signed with. */
|
|
889
|
+
secret: string;
|
|
890
|
+
}
|
|
891
|
+
/** One proxy's check. */
|
|
892
|
+
interface ProxyCheck {
|
|
893
|
+
/** The proxy. */
|
|
894
|
+
id: string;
|
|
895
|
+
/** Whether it answered. */
|
|
896
|
+
ok: boolean;
|
|
897
|
+
/** Where its traffic actually leaves. */
|
|
898
|
+
exitIp?: string | null;
|
|
899
|
+
/** Why it failed. */
|
|
900
|
+
error?: string;
|
|
901
|
+
}
|
|
902
|
+
/** Where a persona's proxy should be. */
|
|
903
|
+
interface GeoHint {
|
|
904
|
+
/** Two-letter country, optionally a region. */
|
|
905
|
+
geo?: string;
|
|
906
|
+
}
|
|
907
|
+
/** A persona to create. */
|
|
908
|
+
interface PersonaCreate {
|
|
909
|
+
/** Its display name. */
|
|
910
|
+
name?: string;
|
|
911
|
+
/** Device choices, fixed for its life. */
|
|
912
|
+
prefs?: PersonaPrefs;
|
|
913
|
+
/** Where its proxy should be. */
|
|
914
|
+
proxy?: GeoHint;
|
|
915
|
+
/** How many browsers may run as it at once; null for no cap. */
|
|
916
|
+
maxConcurrent?: number | null;
|
|
917
|
+
}
|
|
918
|
+
/** What may change on a persona. Never the device. */
|
|
919
|
+
interface PersonaUpdate {
|
|
920
|
+
/** Its display name. */
|
|
921
|
+
name?: string;
|
|
922
|
+
/** How many browsers may run as it at once; null for no cap. */
|
|
923
|
+
maxConcurrent?: number | null;
|
|
924
|
+
/** Where its proxy should be; null clears the hint. */
|
|
925
|
+
proxy?: GeoHint | null;
|
|
926
|
+
}
|
|
927
|
+
/** Options for a clone. */
|
|
928
|
+
interface CloneOptions {
|
|
929
|
+
/** The new persona's name. */
|
|
930
|
+
name?: string;
|
|
931
|
+
}
|
|
932
|
+
/** What a persona may claim, per platform. */
|
|
933
|
+
interface PersonaOptions {
|
|
934
|
+
/** The platforms on offer. */
|
|
935
|
+
platforms: string[];
|
|
936
|
+
/** Timezones each platform may coherently claim. */
|
|
937
|
+
timezones: Record<string, string[]>;
|
|
938
|
+
/** Locales each platform may coherently claim. */
|
|
939
|
+
locales: Record<string, string[]>;
|
|
940
|
+
}
|
|
941
|
+
/** The proxy a persona is pinned to. */
|
|
942
|
+
interface PinnedProxy {
|
|
943
|
+
/** The proxy's id. */
|
|
944
|
+
id: string;
|
|
945
|
+
/** Its display name. */
|
|
946
|
+
label: string;
|
|
947
|
+
}
|
|
948
|
+
/** The outcome of pinning a proxy. */
|
|
949
|
+
interface ProxyPin {
|
|
950
|
+
/** Whether it was saved. */
|
|
951
|
+
ok: boolean;
|
|
952
|
+
/** The proxy now pinned, or null when assignment is left to connect time. */
|
|
953
|
+
proxy: PinnedProxy | null;
|
|
954
|
+
}
|
|
955
|
+
/** A stored second factor, as confirmed. */
|
|
956
|
+
interface MfaSaved {
|
|
957
|
+
/** Whether it is stored. */
|
|
958
|
+
configured: boolean;
|
|
959
|
+
/** Which kind of factor. */
|
|
960
|
+
type: string;
|
|
961
|
+
}
|
|
962
|
+
/** A site login the persona can use. Never the password. */
|
|
963
|
+
interface SiteLogin {
|
|
964
|
+
/** The site. */
|
|
965
|
+
domain: string;
|
|
966
|
+
/** The account name. */
|
|
967
|
+
username: string;
|
|
968
|
+
}
|
|
969
|
+
/** A stored site login, as confirmed. */
|
|
970
|
+
interface CredentialsSaved extends SiteLogin {
|
|
971
|
+
/** Whether it is stored. */
|
|
972
|
+
configured: boolean;
|
|
973
|
+
}
|
|
974
|
+
/** The sites a persona can sign in to. */
|
|
975
|
+
interface SiteLogins {
|
|
976
|
+
/** Usernames only. */
|
|
977
|
+
credentials: SiteLogin[];
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* The shapes Browser's methods take and return that are not part of the
|
|
982
|
+
* exported types: tab listings, dialog answers, share links and the like.
|
|
983
|
+
* Named here so each field can say what it is.
|
|
984
|
+
*/
|
|
985
|
+
|
|
986
|
+
/** What `type()` reports back. */
|
|
987
|
+
interface TypeResult {
|
|
988
|
+
/** An autocomplete list opened under the field; pick from it before moving on. */
|
|
989
|
+
suggestions_visible?: boolean;
|
|
990
|
+
}
|
|
991
|
+
/** The dialog `handleDialog()` answered. */
|
|
992
|
+
interface DialogResult {
|
|
993
|
+
/** alert, confirm, prompt or beforeunload. */
|
|
994
|
+
type: string;
|
|
995
|
+
/** The dialog's text. */
|
|
996
|
+
message: string;
|
|
997
|
+
/** Whether it was accepted. */
|
|
998
|
+
accepted: boolean;
|
|
999
|
+
}
|
|
1000
|
+
/** A point on the page, in CSS pixels. */
|
|
1001
|
+
interface Point {
|
|
1002
|
+
/** From the left edge. */
|
|
1003
|
+
x: number;
|
|
1004
|
+
/** From the top edge. */
|
|
1005
|
+
y: number;
|
|
1006
|
+
}
|
|
1007
|
+
/** One open tab. */
|
|
1008
|
+
interface Tab {
|
|
1009
|
+
/** The tab's id, for `switchTab()` and `closeTab()`. */
|
|
1010
|
+
id: string;
|
|
1011
|
+
/** The page it shows. */
|
|
1012
|
+
url: string;
|
|
1013
|
+
/** The page's title. */
|
|
1014
|
+
title: string;
|
|
1015
|
+
/** Whether it is the tab commands act on. */
|
|
1016
|
+
active: boolean;
|
|
1017
|
+
}
|
|
1018
|
+
/** Task values for `ask()`. */
|
|
1019
|
+
interface AskValues {
|
|
1020
|
+
/** Values the agent can read. */
|
|
1021
|
+
data?: RunData;
|
|
1022
|
+
/** Values the agent never sees. */
|
|
1023
|
+
secrets?: RunData;
|
|
1024
|
+
}
|
|
1025
|
+
/** How `play()` handles a step that no longer fits. */
|
|
1026
|
+
interface PlayOptions {
|
|
1027
|
+
/** Let the agent finish the task and save its fix as a draft. Default true. */
|
|
1028
|
+
autoHeal?: boolean;
|
|
1029
|
+
}
|
|
1030
|
+
/** What `submit()` runs: a prompt for the agent, or a saved playbook. */
|
|
1031
|
+
type Task = {
|
|
1032
|
+
/** A natural-language task for the agent. */
|
|
1033
|
+
prompt: string;
|
|
1034
|
+
} | {
|
|
1035
|
+
/** The name of a saved playbook. */
|
|
1036
|
+
playbook: string;
|
|
1037
|
+
};
|
|
1038
|
+
/** How a `shareUrl()` link works. */
|
|
1039
|
+
interface ShareOptions {
|
|
1040
|
+
/** Let whoever opens it act in the browser. Default view-only. */
|
|
1041
|
+
control?: boolean;
|
|
1042
|
+
/** How long it lasts. Default one hour. */
|
|
1043
|
+
expiresInSeconds?: number;
|
|
1044
|
+
}
|
|
1045
|
+
/** A link from `shareUrl()`. */
|
|
1046
|
+
interface ShareLink {
|
|
1047
|
+
/** The link to hand out. */
|
|
1048
|
+
url: string;
|
|
1049
|
+
/** Its credential's id, for `revokeShare()`. */
|
|
1050
|
+
id: string;
|
|
1051
|
+
/** When it stops working, in epoch milliseconds; null for never. */
|
|
1052
|
+
expiresAt: number | null;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/** The callbacks a run can fire. */
|
|
1056
|
+
type RunCallbacks = Pick<SubmitOptions, 'onSuccess' | 'onFailure' | 'onHumanAttention' | 'onHealed'>;
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* Run: a task submitted with `browser.submit()`, running in the background.
|
|
1060
|
+
* The polling itself lives in run-watch.ts.
|
|
1061
|
+
*/
|
|
1062
|
+
|
|
1063
|
+
/** A submitted task. Callbacks fire as it changes; `done` settles when it ends. */
|
|
1064
|
+
declare class Run {
|
|
1065
|
+
private readonly http;
|
|
1066
|
+
readonly id: string;
|
|
1067
|
+
/** Settles with the result when the run succeeds, or rejects when it fails. */
|
|
1068
|
+
readonly done: Promise<RunResult>;
|
|
1069
|
+
/** Starts watching the run straight away. */
|
|
1070
|
+
constructor(http: Http, id: string, callbacks: RunCallbacks, pollMs?: number);
|
|
1071
|
+
/** The run's current state. */
|
|
1072
|
+
status(): Promise<RunInfo>;
|
|
1073
|
+
/** Answer the open attention request: `'done'` after handling it by hand, or your reply to the agent. */
|
|
1074
|
+
respond(response?: string): Promise<void>;
|
|
1075
|
+
/** Polls until the run ends, firing callbacks on the way. */
|
|
1076
|
+
private watch;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Browser: one running browser, driven through the API. Page actions go
|
|
1081
|
+
* through the command endpoint; CAPTCHA, MFA, agent runs, playbooks and live
|
|
1082
|
+
* view links have their own endpoints. The small rules the methods share
|
|
1083
|
+
* (element ids, aimed scrolls, agent errors) are the functions below the class.
|
|
1084
|
+
*/
|
|
1085
|
+
|
|
494
1086
|
/**
|
|
495
1087
|
* One running browser.
|
|
496
1088
|
*
|
|
@@ -501,54 +1093,59 @@ interface ControlOverview {
|
|
|
501
1093
|
declare class Browser {
|
|
502
1094
|
private readonly http;
|
|
503
1095
|
private readonly autoCaptcha;
|
|
1096
|
+
/** The browser's id. */
|
|
504
1097
|
readonly id: string;
|
|
1098
|
+
/** Which provider runs it. */
|
|
505
1099
|
readonly provider: string;
|
|
1100
|
+
/** Which persona it runs as. */
|
|
506
1101
|
readonly persona: string;
|
|
507
1102
|
/** Point Playwright, Puppeteer or browser-use here. */
|
|
508
1103
|
readonly cdpUrl?: string;
|
|
1104
|
+
/** Wraps a started browser; `autoCaptcha` solves CAPTCHAs after every `goto()`. */
|
|
509
1105
|
constructor(http: Http, info: StartResult, autoCaptcha: boolean);
|
|
1106
|
+
/** Runs one browser command; a command that ran and failed throws. */
|
|
510
1107
|
private command;
|
|
1108
|
+
/** Navigates, then clears any CAPTCHA when `captcha: 'auto'` was asked for. */
|
|
511
1109
|
goto(url: string): Promise<void>;
|
|
512
|
-
/**
|
|
513
|
-
|
|
1110
|
+
/**
|
|
1111
|
+
* The page, written as markdown (the default), TOON or JSONL, plus its blocks and
|
|
1112
|
+
* the numbered elements to act on.
|
|
1113
|
+
*/
|
|
1114
|
+
analyze(options?: AnalyzeOptions): Promise<Analysis>;
|
|
514
1115
|
/** Only the visible elements, which is what an agent almost always wants. */
|
|
515
1116
|
elements(): Promise<Element[]>;
|
|
1117
|
+
/** Clicks an element by its id from `analyze()`. */
|
|
516
1118
|
click(elementId: number | string): Promise<void>;
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
1119
|
+
/** Types into an element by its id from `analyze()`. */
|
|
1120
|
+
type(elementId: number | string, text: string): Promise<TypeResult>;
|
|
1121
|
+
/** A valid element id, or an OyaError saying where ids come from. */
|
|
520
1122
|
private elementId;
|
|
1123
|
+
/** Presses one key, such as Enter or Escape. */
|
|
521
1124
|
pressKey(key: string): Promise<void>;
|
|
522
1125
|
/**
|
|
523
1126
|
* Answer a native dialog holding the page. alert() and beforeunload are
|
|
524
1127
|
* answered for you; a confirm() or prompt() waits for this, and every other
|
|
525
1128
|
* command fails fast with the dialog's text until it is answered.
|
|
526
1129
|
*/
|
|
527
|
-
handleDialog(accept: boolean, promptText?: string): Promise<
|
|
528
|
-
type: string;
|
|
529
|
-
message: string;
|
|
530
|
-
accepted: boolean;
|
|
531
|
-
}>;
|
|
1130
|
+
handleDialog(accept: boolean, promptText?: string): Promise<DialogResult>;
|
|
532
1131
|
/** `at` aims the wheel at an inner scroller (a results panel, a chat pane) instead of the page. */
|
|
533
|
-
scroll(direction: 'up' | 'down' | 'top' | 'bottom', amount?: number, at?:
|
|
534
|
-
|
|
535
|
-
y: number;
|
|
536
|
-
}): Promise<void>;
|
|
1132
|
+
scroll(direction: 'up' | 'down' | 'top' | 'bottom', amount?: number, at?: Point): Promise<void>;
|
|
1133
|
+
/** Waits until `selector` matches, up to `timeout` milliseconds. */
|
|
537
1134
|
waitFor(selector: string, timeout?: number): Promise<void>;
|
|
538
1135
|
/** A `data:image/…;base64,` URL. PNG or JPEG depending on the driver. */
|
|
539
1136
|
screenshot(): Promise<string>;
|
|
1137
|
+
/** The active tab's URL, or empty when there is none. */
|
|
540
1138
|
url(): Promise<string>;
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
title: string;
|
|
545
|
-
active: boolean;
|
|
546
|
-
}>>;
|
|
1139
|
+
/** Every open tab. */
|
|
1140
|
+
tabs(): Promise<Array<Tab>>;
|
|
1141
|
+
/** Opens a tab, optionally at `url`, and returns its id. */
|
|
547
1142
|
openTab(url?: string): Promise<string>;
|
|
1143
|
+
/** Makes a tab the one commands act on. */
|
|
548
1144
|
switchTab(tabId: string): Promise<void>;
|
|
1145
|
+
/** Closes a tab. */
|
|
549
1146
|
closeTab(tabId: string): Promise<void>;
|
|
550
1147
|
/**
|
|
551
|
-
|
|
1148
|
+
* Detect and clear a CAPTCHA. Providers that solve natively are left to do
|
|
552
1149
|
* it; everything else goes to the configured solver.
|
|
553
1150
|
*/
|
|
554
1151
|
solveCaptcha(): Promise<CaptchaResult>;
|
|
@@ -563,10 +1160,7 @@ declare class Browser {
|
|
|
563
1160
|
* the matching option; `secrets` it never sees. It types both through placeholders,
|
|
564
1161
|
* with filters like `{{name|first}}`, so a playbook saved from the run stores no values.
|
|
565
1162
|
*/
|
|
566
|
-
ask(prompt: string, { data, secrets }?:
|
|
567
|
-
data?: RunData;
|
|
568
|
-
secrets?: RunData;
|
|
569
|
-
}): Promise<string>;
|
|
1163
|
+
ask(prompt: string, { data, secrets }?: AskValues): Promise<string>;
|
|
570
1164
|
/**
|
|
571
1165
|
* Save the last `ask()` on this browser as a named playbook. Every value that was
|
|
572
1166
|
* typed, picked or clicked becomes a variable, with what the run used kept in
|
|
@@ -581,31 +1175,17 @@ declare class Browser {
|
|
|
581
1175
|
* saved as a draft (`healed`, `draft`); off, the step's error is thrown.
|
|
582
1176
|
* Play `'<name>:draft'` to try a draft before promoting it.
|
|
583
1177
|
*/
|
|
584
|
-
play(name: string, data?: RunData, { autoHeal }?:
|
|
585
|
-
autoHeal?: boolean;
|
|
586
|
-
}): Promise<PlayResult>;
|
|
1178
|
+
play(name: string, data?: RunData, { autoHeal }?: PlayOptions): Promise<PlayResult>;
|
|
587
1179
|
/**
|
|
588
1180
|
* Start a prompt or playbook in the background and hear back through callbacks.
|
|
589
1181
|
* `onHumanAttention` fires for an unsolved CAPTCHA, an unfinished MFA, the agent
|
|
590
1182
|
* asking for help, or a replay the agent could not heal; the run waits (up to 30
|
|
591
1183
|
* minutes) until you call `respond()`.
|
|
592
1184
|
*/
|
|
593
|
-
submit(task:
|
|
594
|
-
prompt: string;
|
|
595
|
-
} | {
|
|
596
|
-
playbook: string;
|
|
597
|
-
}, options?: SubmitOptions): Promise<Run>;
|
|
1185
|
+
submit(task: Task, options?: SubmitOptions): Promise<Run>;
|
|
598
1186
|
/**
|
|
599
|
-
* Watch it work: the console, opened on this browser.
|
|
600
|
-
*
|
|
601
|
-
* This used to return the raw frame stream with the project's API key in the
|
|
602
|
-
* query string — a permanent credential in browser history, Referer headers
|
|
603
|
-
* and every proxy log on the way, and a URL that renders as a wall of
|
|
604
|
-
* text/event-stream if a person actually opens it. It is the console deep
|
|
605
|
-
* link now, the same one the server hands back from `completeMfa()`, and it
|
|
606
|
-
* carries no credential at all.
|
|
607
|
-
*
|
|
608
|
-
* For the frames themselves, use `liveStreamUrl()`.
|
|
1187
|
+
* Watch it work: the console, opened on this browser. It carries no
|
|
1188
|
+
* credential. For the frames themselves, use `liveStreamUrl()`.
|
|
609
1189
|
*/
|
|
610
1190
|
liveViewUrl(): string;
|
|
611
1191
|
/**
|
|
@@ -625,14 +1205,7 @@ declare class Browser {
|
|
|
625
1205
|
* rest of your project. Anyone holding the link has that access until it
|
|
626
1206
|
* expires or you revoke it, so treat it like a password.
|
|
627
1207
|
*/
|
|
628
|
-
shareUrl({ control, expiresInSeconds }?:
|
|
629
|
-
control?: boolean;
|
|
630
|
-
expiresInSeconds?: number;
|
|
631
|
-
}): Promise<{
|
|
632
|
-
url: string;
|
|
633
|
-
id: string;
|
|
634
|
-
expiresAt: number | null;
|
|
635
|
-
}>;
|
|
1208
|
+
shareUrl({ control, expiresInSeconds }?: ShareOptions): Promise<ShareLink>;
|
|
636
1209
|
/** Revoke a link from `shareUrl()` before it expires, by the id it returned. */
|
|
637
1210
|
revokeShare(id: string): Promise<void>;
|
|
638
1211
|
/** Counters, health and the last 50 things this browser did. */
|
|
@@ -647,18 +1220,6 @@ declare class Browser {
|
|
|
647
1220
|
/** @deprecated use stop() — close() only dropped the socket, and a cloud browser redialled. */
|
|
648
1221
|
close(): Promise<void>;
|
|
649
1222
|
}
|
|
650
|
-
type RunCallbacks = Pick<SubmitOptions, 'onSuccess' | 'onFailure' | 'onHumanAttention' | 'onHealed'>;
|
|
651
|
-
/** A submitted task. Callbacks fire as it changes; `done` settles when it ends. */
|
|
652
|
-
declare class Run {
|
|
653
|
-
private readonly http;
|
|
654
|
-
readonly id: string;
|
|
655
|
-
readonly done: Promise<RunResult>;
|
|
656
|
-
constructor(http: Http, id: string, callbacks: RunCallbacks, pollMs?: number);
|
|
657
|
-
status(): Promise<RunInfo>;
|
|
658
|
-
/** Answer the open attention request: `'done'` after handling it by hand, or your reply to the agent. */
|
|
659
|
-
respond(response?: string): Promise<void>;
|
|
660
|
-
private watch;
|
|
661
|
-
}
|
|
662
1223
|
|
|
663
1224
|
/**
|
|
664
1225
|
* Files as task values.
|
|
@@ -678,100 +1239,52 @@ declare const MAX_FILE_BYTES: number;
|
|
|
678
1239
|
* from the extension.
|
|
679
1240
|
*/
|
|
680
1241
|
declare function file(source: string | Uint8Array | Blob, options?: {
|
|
1242
|
+
/** The filename the site sees. */
|
|
681
1243
|
name?: string;
|
|
1244
|
+
/** The MIME type, instead of the one guessed from the extension. */
|
|
682
1245
|
type?: string;
|
|
683
1246
|
}): Promise<FileValue>;
|
|
684
1247
|
|
|
685
|
-
/**
|
|
686
|
-
* @oya-ai/browser — thousands of browsers, one API.
|
|
687
|
-
*
|
|
688
|
-
* import { Oya } from '@oya-ai/browser';
|
|
689
|
-
*
|
|
690
|
-
* const oya = new Oya(); // OYA_API_KEY
|
|
691
|
-
* const browser = await oya.browser.start({ persona: 'auto', captcha: 'auto' });
|
|
692
|
-
* await browser.goto('https://example.com');
|
|
693
|
-
*
|
|
694
|
-
* Which provider actually runs the browser — Oya Cloud, your own machines,
|
|
695
|
-
* Browser Use, Browserbase, Steel, Anchor, or a CDP URL you hand us — is
|
|
696
|
-
* configuration on your API key, not something this code has to know.
|
|
697
|
-
*/
|
|
698
|
-
|
|
1248
|
+
/** The client: one API key, every browser behind it. */
|
|
699
1249
|
declare class Oya {
|
|
1250
|
+
/** The one HTTP path every call goes through. */
|
|
700
1251
|
private readonly http;
|
|
1252
|
+
/** Reads the key and URL from `options`, then OYA_API_KEY and OYA_BASE_URL. Throws without a key. */
|
|
701
1253
|
constructor(options?: OyaOptions);
|
|
1254
|
+
/** Start, reattach to, list and stop browsers. */
|
|
702
1255
|
readonly browser: {
|
|
703
|
-
/** Start a browser and wait until it can take commands. */
|
|
704
1256
|
start: (options?: StartOptions) => Promise<Browser>;
|
|
705
|
-
/** Reattach to a browser that is already running. */
|
|
706
1257
|
get: (id: string) => Promise<Browser>;
|
|
707
1258
|
list: () => Promise<BrowserInfo[]>;
|
|
708
|
-
|
|
709
|
-
stop: (ids: string[] | "all") => Promise<{
|
|
710
|
-
stopped: number;
|
|
711
|
-
results: StopResult[];
|
|
712
|
-
}>;
|
|
1259
|
+
stop: (ids: string[] | "all") => Promise<StopManyResult>;
|
|
713
1260
|
stopAll: () => Promise<number>;
|
|
714
1261
|
};
|
|
715
1262
|
/** Durable operational controls, including disconnected and cleanup-pending sessions. */
|
|
716
1263
|
readonly control: {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
1264
|
+
createWebhook: (url: string, types?: string[]) => Promise<Webhook>;
|
|
1265
|
+
removeWebhook: (id: string) => Promise<Ack>;
|
|
1266
|
+
replayDelivery: (id: string) => Promise<Ack>;
|
|
1267
|
+
members: () => Promise<MemberList>;
|
|
1268
|
+
inviteMember: (role?: ControlRole) => Promise<Invite>;
|
|
1269
|
+
removeMember: (userId: string) => Promise<Ack>;
|
|
1270
|
+
createCredential: (options: CredentialRequest) => Promise<NewCredential>;
|
|
1271
|
+
revokeCredential: (id: string) => Promise<Ack>;
|
|
1272
|
+
recover: (id: string, replace?: boolean) => Promise<unknown>;
|
|
1273
|
+
ticket: (id: string) => Promise<Ticket>;
|
|
1274
|
+
events: (after?: number) => Promise<EventPage>;
|
|
721
1275
|
cancel: (id: string) => Promise<ControlSession>;
|
|
722
1276
|
stop: (id: string, force?: boolean) => Promise<StopResult>;
|
|
723
1277
|
takeover: (id: string, action: "acquire" | "release" | "resume") => Promise<ControlSession["control"]>;
|
|
724
1278
|
input: (id: string, action: HumanInputAction, params: Record<string, unknown>) => Promise<unknown>;
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
}>;
|
|
730
|
-
events: (after?: number) => Promise<{
|
|
731
|
-
events: ControlEvent[];
|
|
732
|
-
cursor: number;
|
|
733
|
-
}>;
|
|
734
|
-
createCredential: (options: {
|
|
735
|
-
role: ControlRole;
|
|
736
|
-
label?: string;
|
|
737
|
-
expiresAt?: number;
|
|
738
|
-
}) => Promise<ControlCredential & {
|
|
739
|
-
token: string;
|
|
740
|
-
}>;
|
|
741
|
-
revokeCredential: (id: string) => Promise<{
|
|
742
|
-
ok: boolean;
|
|
743
|
-
}>;
|
|
744
|
-
members: () => Promise<{
|
|
745
|
-
owner: string | null;
|
|
746
|
-
members: {
|
|
747
|
-
userId: string;
|
|
748
|
-
role: ControlRole;
|
|
749
|
-
}[];
|
|
750
|
-
}>;
|
|
751
|
-
inviteMember: (role?: ControlRole) => Promise<{
|
|
752
|
-
code: string;
|
|
753
|
-
expiresIn: number;
|
|
754
|
-
}>;
|
|
755
|
-
removeMember: (userId: string) => Promise<{
|
|
756
|
-
ok: boolean;
|
|
757
|
-
}>;
|
|
758
|
-
createWebhook: (url: string, types?: string[]) => Promise<{
|
|
759
|
-
id: string;
|
|
760
|
-
secret: string;
|
|
761
|
-
}>;
|
|
762
|
-
removeWebhook: (id: string) => Promise<{
|
|
763
|
-
ok: boolean;
|
|
764
|
-
}>;
|
|
765
|
-
replayDelivery: (id: string) => Promise<{
|
|
766
|
-
ok: boolean;
|
|
767
|
-
}>;
|
|
1279
|
+
overview: () => Promise<ControlOverview>;
|
|
1280
|
+
sessions: () => Promise<ControlSession[]>;
|
|
1281
|
+
session: (id: string) => Promise<ControlSession>;
|
|
1282
|
+
settings: (changes: Partial<ProjectSettings>) => Promise<ControlOverview["project"]>;
|
|
768
1283
|
};
|
|
769
1284
|
/** Playbooks saved with `browser.toPlaybook()`. */
|
|
770
1285
|
readonly playbooks: {
|
|
771
1286
|
list: () => Promise<PlaybookSummary[]>;
|
|
772
|
-
/** Delete a playbook and its draft, or only the draft with `'<name>:draft'`. */
|
|
773
1287
|
remove: (name: string) => Promise<void>;
|
|
774
|
-
/** Replace a playbook with the draft a healed replay saved. Try it first with `browser.play('<name>:draft')`. */
|
|
775
1288
|
promote: (name: string) => Promise<Playbook>;
|
|
776
1289
|
};
|
|
777
1290
|
/**
|
|
@@ -782,84 +1295,24 @@ declare class Oya {
|
|
|
782
1295
|
list: () => Promise<ProxyInfo[]>;
|
|
783
1296
|
create: (proxy: ProxyCreate) => Promise<ProxyInfo>;
|
|
784
1297
|
remove: (id: string) => Promise<void>;
|
|
785
|
-
|
|
786
|
-
check: () => Promise<Array<{
|
|
787
|
-
id: string;
|
|
788
|
-
ok: boolean;
|
|
789
|
-
exitIp?: string | null;
|
|
790
|
-
error?: string;
|
|
791
|
-
}>>;
|
|
1298
|
+
check: () => Promise<Array<ProxyCheck>>;
|
|
792
1299
|
};
|
|
1300
|
+
/** Identities: fingerprint, cookie jar and proxy bound together, plus their stored factors and logins. */
|
|
793
1301
|
readonly personas: {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
*/
|
|
800
|
-
create: (options?: {
|
|
801
|
-
name?: string;
|
|
802
|
-
prefs?: PersonaPrefs;
|
|
803
|
-
proxy?: {
|
|
804
|
-
geo?: string;
|
|
805
|
-
};
|
|
806
|
-
maxConcurrent?: number | null;
|
|
807
|
-
}) => Promise<PersonaInfo>;
|
|
808
|
-
/** Name, concurrency cap and proxy hint. Never the device — clone for that. */
|
|
809
|
-
update: (id: string, changes: {
|
|
810
|
-
name?: string;
|
|
811
|
-
maxConcurrent?: number | null;
|
|
812
|
-
proxy?: {
|
|
813
|
-
geo?: string;
|
|
814
|
-
} | null;
|
|
815
|
-
}) => Promise<PersonaInfo>;
|
|
816
|
-
/** A new persona of the same kind of device: same choices, fresh identity, empty jar. */
|
|
817
|
-
clone: (id: string, options?: {
|
|
818
|
-
name?: string;
|
|
819
|
-
}) => Promise<PersonaInfo>;
|
|
820
|
-
/** The fingerprint these choices would produce. Persists nothing. */
|
|
1302
|
+
setCredentials: (id: string, config: SiteCredentials) => Promise<CredentialsSaved>;
|
|
1303
|
+
credentials: (id: string) => Promise<SiteLogins>;
|
|
1304
|
+
clearCredentials: (id: string, domain: string) => Promise<void>;
|
|
1305
|
+
setMfa: (id: string, config: MfaConfig) => Promise<MfaSaved>;
|
|
1306
|
+
clearMfa: (id: string, domain?: string) => Promise<void>;
|
|
821
1307
|
preview: (prefs?: PersonaPrefs) => Promise<Fingerprint>;
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
platforms: string[];
|
|
825
|
-
timezones: Record<string, string[]>;
|
|
826
|
-
locales: Record<string, string[]>;
|
|
827
|
-
}>;
|
|
828
|
-
/** Pin the persona to one of your proxies, or `null` to let assignment happen at connect. */
|
|
829
|
-
pinProxy: (id: string, proxyId: string | null) => Promise<{
|
|
830
|
-
ok: boolean;
|
|
831
|
-
proxy: {
|
|
832
|
-
id: string;
|
|
833
|
-
label: string;
|
|
834
|
-
} | null;
|
|
835
|
-
}>;
|
|
1308
|
+
options: () => Promise<PersonaOptions>;
|
|
1309
|
+
pinProxy: (id: string, proxyId: string | null) => Promise<ProxyPin>;
|
|
836
1310
|
remove: (id: string) => Promise<void>;
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
clearMfa: (id: string, domain?: string) => Promise<void>;
|
|
843
|
-
/**
|
|
844
|
-
* Store a site login for this identity. Sealed at rest, never read back.
|
|
845
|
-
*
|
|
846
|
-
* Signing in once on the desktop and inheriting the cookies is still the
|
|
847
|
-
* better path. This is for portals that expire a session server-side
|
|
848
|
-
* between runs, where an unattended run has nothing else to recover with.
|
|
849
|
-
*/
|
|
850
|
-
setCredentials: (id: string, config: SiteCredentials) => Promise<{
|
|
851
|
-
configured: boolean;
|
|
852
|
-
domain: string;
|
|
853
|
-
username: string;
|
|
854
|
-
}>;
|
|
855
|
-
/** Which sites this identity can sign in to. Usernames only. */
|
|
856
|
-
credentials: (id: string) => Promise<{
|
|
857
|
-
credentials: {
|
|
858
|
-
domain: string;
|
|
859
|
-
username: string;
|
|
860
|
-
}[];
|
|
861
|
-
}>;
|
|
862
|
-
clearCredentials: (id: string, domain: string) => Promise<void>;
|
|
1311
|
+
list: () => Promise<PersonaInfo[]>;
|
|
1312
|
+
get: (id: string) => Promise<PersonaInfo>;
|
|
1313
|
+
create: (options?: PersonaCreate) => Promise<PersonaInfo>;
|
|
1314
|
+
update: (id: string, changes: PersonaUpdate) => Promise<PersonaInfo>;
|
|
1315
|
+
clone: (id: string, options?: CloneOptions) => Promise<PersonaInfo>;
|
|
863
1316
|
};
|
|
864
1317
|
/**
|
|
865
1318
|
* This key's settings: LLM credentials, browser provider, solver.
|
|
@@ -878,78 +1331,25 @@ declare class Oya {
|
|
|
878
1331
|
};
|
|
879
1332
|
/** Saved profiles. `personas` is retained as an alias for existing clients. */
|
|
880
1333
|
readonly profiles: {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
*/
|
|
887
|
-
create: (options?: {
|
|
888
|
-
name?: string;
|
|
889
|
-
prefs?: PersonaPrefs;
|
|
890
|
-
proxy?: {
|
|
891
|
-
geo?: string;
|
|
892
|
-
};
|
|
893
|
-
maxConcurrent?: number | null;
|
|
894
|
-
}) => Promise<PersonaInfo>;
|
|
895
|
-
/** Name, concurrency cap and proxy hint. Never the device — clone for that. */
|
|
896
|
-
update: (id: string, changes: {
|
|
897
|
-
name?: string;
|
|
898
|
-
maxConcurrent?: number | null;
|
|
899
|
-
proxy?: {
|
|
900
|
-
geo?: string;
|
|
901
|
-
} | null;
|
|
902
|
-
}) => Promise<PersonaInfo>;
|
|
903
|
-
/** A new persona of the same kind of device: same choices, fresh identity, empty jar. */
|
|
904
|
-
clone: (id: string, options?: {
|
|
905
|
-
name?: string;
|
|
906
|
-
}) => Promise<PersonaInfo>;
|
|
907
|
-
/** The fingerprint these choices would produce. Persists nothing. */
|
|
1334
|
+
setCredentials: (id: string, config: SiteCredentials) => Promise<CredentialsSaved>;
|
|
1335
|
+
credentials: (id: string) => Promise<SiteLogins>;
|
|
1336
|
+
clearCredentials: (id: string, domain: string) => Promise<void>;
|
|
1337
|
+
setMfa: (id: string, config: MfaConfig) => Promise<MfaSaved>;
|
|
1338
|
+
clearMfa: (id: string, domain?: string) => Promise<void>;
|
|
908
1339
|
preview: (prefs?: PersonaPrefs) => Promise<Fingerprint>;
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
platforms: string[];
|
|
912
|
-
timezones: Record<string, string[]>;
|
|
913
|
-
locales: Record<string, string[]>;
|
|
914
|
-
}>;
|
|
915
|
-
/** Pin the persona to one of your proxies, or `null` to let assignment happen at connect. */
|
|
916
|
-
pinProxy: (id: string, proxyId: string | null) => Promise<{
|
|
917
|
-
ok: boolean;
|
|
918
|
-
proxy: {
|
|
919
|
-
id: string;
|
|
920
|
-
label: string;
|
|
921
|
-
} | null;
|
|
922
|
-
}>;
|
|
1340
|
+
options: () => Promise<PersonaOptions>;
|
|
1341
|
+
pinProxy: (id: string, proxyId: string | null) => Promise<ProxyPin>;
|
|
923
1342
|
remove: (id: string) => Promise<void>;
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
clearMfa: (id: string, domain?: string) => Promise<void>;
|
|
930
|
-
/**
|
|
931
|
-
* Store a site login for this identity. Sealed at rest, never read back.
|
|
932
|
-
*
|
|
933
|
-
* Signing in once on the desktop and inheriting the cookies is still the
|
|
934
|
-
* better path. This is for portals that expire a session server-side
|
|
935
|
-
* between runs, where an unattended run has nothing else to recover with.
|
|
936
|
-
*/
|
|
937
|
-
setCredentials: (id: string, config: SiteCredentials) => Promise<{
|
|
938
|
-
configured: boolean;
|
|
939
|
-
domain: string;
|
|
940
|
-
username: string;
|
|
941
|
-
}>;
|
|
942
|
-
/** Which sites this identity can sign in to. Usernames only. */
|
|
943
|
-
credentials: (id: string) => Promise<{
|
|
944
|
-
credentials: {
|
|
945
|
-
domain: string;
|
|
946
|
-
username: string;
|
|
947
|
-
}[];
|
|
948
|
-
}>;
|
|
949
|
-
clearCredentials: (id: string, domain: string) => Promise<void>;
|
|
1343
|
+
list: () => Promise<PersonaInfo[]>;
|
|
1344
|
+
get: (id: string) => Promise<PersonaInfo>;
|
|
1345
|
+
create: (options?: PersonaCreate) => Promise<PersonaInfo>;
|
|
1346
|
+
update: (id: string, changes: PersonaUpdate) => Promise<PersonaInfo>;
|
|
1347
|
+
clone: (id: string, options?: CloneOptions) => Promise<PersonaInfo>;
|
|
950
1348
|
};
|
|
1349
|
+
/** What this key has spent. */
|
|
951
1350
|
usage(): Promise<unknown>;
|
|
1351
|
+
/** Waits for a starting browser to dial in, through this client's own list and session calls. */
|
|
952
1352
|
private waitUntilConnected;
|
|
953
1353
|
}
|
|
954
1354
|
|
|
955
|
-
export { type Activity, type Analysis, type AttentionRequest, Browser, type BrowserDetail, type BrowserInfo, type CaptchaResult, type CaptchaSolver, type Config, type ConfigUpdate, type ControlCredential, type ControlEvent, type ControlOverview, type ControlRole, type ControlSession, type Element, type FileValue, type Fingerprint, type Health, type HumanInputAction, type LlmProvider, MAX_FILE_BYTES, type MfaConfig, type MfaResult, Oya, OyaError, type OyaOptions, type PersonaInfo, type PersonaPrefs, type PlayResult, type Playbook, type PlaybookSummary, type ProjectSettings, type Provider, type ProxyCreate, type ProxyInfo, Run, type RunData, type RunInfo, type RunResult, type SiteCredentials, type StartOptions, type StartResult, type StopResult, type SubmitOptions, Oya as default, file };
|
|
1355
|
+
export { type Activity, type Analysis, type AnalyzeOptions, type AttentionRequest, type Block, Browser, type BrowserDetail, type BrowserInfo, type CaptchaResult, type CaptchaSolver, type Config, type ConfigUpdate, type ControlCredential, type ControlEvent, type ControlOverview, type ControlRole, type ControlSession, type Element, type FileValue, type Fingerprint, type Health, type HumanInputAction, type LlmProvider, MAX_FILE_BYTES, type MfaConfig, type MfaResult, Oya, OyaError, type OyaOptions, type PageFormat, type PersonaInfo, type PersonaPrefs, type PlayResult, type Playbook, type PlaybookSummary, type ProjectSettings, type Provider, type ProxyCreate, type ProxyInfo, Run, type RunData, type RunInfo, type RunResult, type SiteCredentials, type StartOptions, type StartResult, type StopResult, type SubmitOptions, Oya as default, file };
|