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