browser-use-sdk 3.6.0 → 3.8.1
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/{chunk-SKUINUZ4.js → chunk-ESJIWN3M.js} +65 -32
- package/dist/chunk-ESJIWN3M.js.map +1 -0
- package/dist/{chunk-4BAZFOC2.cjs → chunk-QMK4AUMH.cjs} +66 -33
- package/dist/chunk-QMK4AUMH.cjs.map +1 -0
- package/dist/{errors-Bp9CqFUs.d.cts → errors-DaHgFhIQ.d.cts} +18 -1
- package/dist/{errors-Bp9CqFUs.d.ts → errors-DaHgFhIQ.d.ts} +18 -1
- package/dist/index.cjs +7 -7
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/v3.cjs +9 -7
- package/dist/v3.cjs.map +1 -1
- package/dist/v3.d.cts +3 -3
- package/dist/v3.d.ts +3 -3
- package/dist/v3.js +4 -2
- package/dist/v3.js.map +1 -1
- package/package.json +10 -4
- package/dist/chunk-4BAZFOC2.cjs.map +0 -1
- package/dist/chunk-SKUINUZ4.js.map +0 -1
|
@@ -10,6 +10,69 @@ var BrowserUseError = class extends Error {
|
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
// src/core/x402.ts
|
|
14
|
+
var X402_BASE_URL_DEFAULT = "https://x402.api.browser-use.com/api/v3";
|
|
15
|
+
var X402_BASE_URL_DEFAULT_V2 = "https://x402.api.browser-use.com/api/v2";
|
|
16
|
+
var X402_BALANCE_BASE_URL_DEFAULT = "https://api.browser-use.com/api/v3";
|
|
17
|
+
function buildWalletAuthMessage(address, issuedAt, nonce) {
|
|
18
|
+
return `Browser Use x402 wallet authentication
|
|
19
|
+
Action: read credit balance
|
|
20
|
+
Wallet: ${address}
|
|
21
|
+
Issued At: ${issuedAt}
|
|
22
|
+
Nonce: ${nonce}`;
|
|
23
|
+
}
|
|
24
|
+
async function getWalletBalance(privateKey, opts = {}) {
|
|
25
|
+
let viem;
|
|
26
|
+
try {
|
|
27
|
+
viem = await import("viem/accounts");
|
|
28
|
+
} catch {
|
|
29
|
+
throw new Error(MISSING_X402);
|
|
30
|
+
}
|
|
31
|
+
const key = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
32
|
+
const account = viem.privateKeyToAccount(key);
|
|
33
|
+
const issuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
34
|
+
const nonce = crypto.randomUUID().replace(/-/g, "");
|
|
35
|
+
const message = buildWalletAuthMessage(account.address, issuedAt, nonce);
|
|
36
|
+
const signature = await account.signMessage({ message });
|
|
37
|
+
const baseUrl = (opts.baseUrl ?? X402_BALANCE_BASE_URL_DEFAULT).replace(/\/$/, "");
|
|
38
|
+
const resp = await fetch(`${baseUrl}/x402/balance`, {
|
|
39
|
+
method: "POST",
|
|
40
|
+
headers: { "Content-Type": "application/json" },
|
|
41
|
+
body: JSON.stringify({ address: account.address, issued_at: issuedAt, nonce, signature, ...opts.extra })
|
|
42
|
+
});
|
|
43
|
+
if (!resp.ok) {
|
|
44
|
+
throw new Error(`x402 balance check failed: ${resp.status} ${await resp.text()}`);
|
|
45
|
+
}
|
|
46
|
+
return await resp.json();
|
|
47
|
+
}
|
|
48
|
+
var MISSING_X402 = "x402 mode requires the optional peer deps. Install them with: npm install @x402/fetch @x402/evm viem (or the equivalent for pnpm/yarn).";
|
|
49
|
+
async function x402ClientFromPrivateKey(privateKey) {
|
|
50
|
+
let viem;
|
|
51
|
+
let fetchPkg;
|
|
52
|
+
let evmPkg;
|
|
53
|
+
try {
|
|
54
|
+
viem = await import("viem/accounts");
|
|
55
|
+
fetchPkg = await import("@x402/fetch");
|
|
56
|
+
evmPkg = await import("@x402/evm");
|
|
57
|
+
} catch (e) {
|
|
58
|
+
throw new Error(MISSING_X402);
|
|
59
|
+
}
|
|
60
|
+
const key = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
61
|
+
const signer = viem.privateKeyToAccount(key);
|
|
62
|
+
const client = new fetchPkg.x402Client();
|
|
63
|
+
client.register("eip155:*", new evmPkg.ExactEvmScheme(signer));
|
|
64
|
+
return client;
|
|
65
|
+
}
|
|
66
|
+
async function wrapFetchWithX402(fetch2, x402Client) {
|
|
67
|
+
let fetchPkg;
|
|
68
|
+
try {
|
|
69
|
+
fetchPkg = await import("@x402/fetch");
|
|
70
|
+
} catch (e) {
|
|
71
|
+
throw new Error(MISSING_X402);
|
|
72
|
+
}
|
|
73
|
+
return fetchPkg.wrapFetchWithPayment(fetch2, x402Client);
|
|
74
|
+
}
|
|
75
|
+
|
|
13
76
|
// src/core/http.ts
|
|
14
77
|
var HttpClient = class {
|
|
15
78
|
apiKey;
|
|
@@ -100,43 +163,13 @@ var HttpClient = class {
|
|
|
100
163
|
}
|
|
101
164
|
};
|
|
102
165
|
|
|
103
|
-
// src/core/x402.ts
|
|
104
|
-
var X402_BASE_URL_DEFAULT = "https://x402.api.browser-use.com/api/v3";
|
|
105
|
-
var X402_BASE_URL_DEFAULT_V2 = "https://x402.api.browser-use.com/api/v2";
|
|
106
|
-
var MISSING_X402 = "x402 mode requires the optional peer deps. Install them with: npm install @x402/fetch @x402/evm viem (or the equivalent for pnpm/yarn).";
|
|
107
|
-
async function x402ClientFromPrivateKey(privateKey) {
|
|
108
|
-
let viem;
|
|
109
|
-
let fetchPkg;
|
|
110
|
-
let evmPkg;
|
|
111
|
-
try {
|
|
112
|
-
viem = await import("viem/accounts");
|
|
113
|
-
fetchPkg = await import("@x402/fetch");
|
|
114
|
-
evmPkg = await import("@x402/evm");
|
|
115
|
-
} catch (e) {
|
|
116
|
-
throw new Error(MISSING_X402);
|
|
117
|
-
}
|
|
118
|
-
const key = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
119
|
-
const signer = viem.privateKeyToAccount(key);
|
|
120
|
-
const client = new fetchPkg.x402Client();
|
|
121
|
-
client.register("eip155:*", new evmPkg.ExactEvmScheme(signer));
|
|
122
|
-
return client;
|
|
123
|
-
}
|
|
124
|
-
async function wrapFetchWithX402(fetch2, x402Client) {
|
|
125
|
-
let fetchPkg;
|
|
126
|
-
try {
|
|
127
|
-
fetchPkg = await import("@x402/fetch");
|
|
128
|
-
} catch (e) {
|
|
129
|
-
throw new Error(MISSING_X402);
|
|
130
|
-
}
|
|
131
|
-
return fetchPkg.wrapFetchWithPayment(fetch2, x402Client);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
166
|
export {
|
|
135
167
|
BrowserUseError,
|
|
136
168
|
HttpClient,
|
|
137
169
|
X402_BASE_URL_DEFAULT,
|
|
138
170
|
X402_BASE_URL_DEFAULT_V2,
|
|
171
|
+
getWalletBalance,
|
|
139
172
|
x402ClientFromPrivateKey,
|
|
140
173
|
wrapFetchWithX402
|
|
141
174
|
};
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
175
|
+
//# sourceMappingURL=chunk-ESJIWN3M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/errors.ts","../src/core/x402.ts","../src/core/http.ts"],"sourcesContent":["export class BrowserUseError extends Error {\n readonly statusCode: number;\n readonly detail: unknown;\n\n constructor(statusCode: number, message: string, detail?: unknown) {\n super(message);\n this.name = \"BrowserUseError\";\n this.statusCode = statusCode;\n this.detail = detail;\n }\n}\n","/**\n * Helpers for the optional x402 (pay-per-request) integration.\n *\n * x402 is an HTTP payment protocol: instead of an API key, requests are\n * authenticated by signing a small USDC payment. See the docs at\n * `cloud/guides/x402` and https://www.x402.org for details.\n *\n * The peer deps `@x402/fetch`, `@x402/evm`, and `viem` are optional. They are\n * imported lazily so users who only use API-key auth never pay the cost.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type X402Client = any;\nexport type FetchLike = (\n input: RequestInfo | URL,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport const X402_BASE_URL_DEFAULT = \"https://x402.api.browser-use.com/api/v3\";\nexport const X402_BASE_URL_DEFAULT_V2 = \"https://x402.api.browser-use.com/api/v2\";\nexport const X402_BALANCE_BASE_URL_DEFAULT = \"https://api.browser-use.com/api/v3\";\n\nexport interface X402WalletBalance {\n wallet: string;\n project_id: string;\n total_credits_usd: number;\n additional_credits_usd: number;\n}\n\nfunction buildWalletAuthMessage(address: string, issuedAt: string, nonce: string): string {\n return (\n \"Browser Use x402 wallet authentication\\n\" +\n \"Action: read credit balance\\n\" +\n `Wallet: ${address}\\n` +\n `Issued At: ${issuedAt}\\n` +\n `Nonce: ${nonce}`\n );\n}\n\n/**\n * Read a wallet-derived project's credit balance\n *\n * Authenticates with an off-chain wallet signature (EIP-191): signs a\n * message proving control of the address; the server resolves the wallet to its\n * project and returns the balance\n */\nexport async function getWalletBalance(\n privateKey: `0x${string}` | string,\n opts: { baseUrl?: string; extra?: Record<string, unknown> } = {},\n): Promise<X402WalletBalance> {\n let viem;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n viem = await import(\"viem/accounts\");\n } catch {\n throw new Error(MISSING_X402);\n }\n const key = privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`;\n const account = viem.privateKeyToAccount(key as `0x${string}`);\n\n const issuedAt = new Date().toISOString();\n const nonce = crypto.randomUUID().replace(/-/g, \"\");\n const message = buildWalletAuthMessage(account.address, issuedAt, nonce);\n const signature = await account.signMessage({ message });\n\n const baseUrl = (opts.baseUrl ?? X402_BALANCE_BASE_URL_DEFAULT).replace(/\\/$/, \"\");\n const resp = await fetch(`${baseUrl}/x402/balance`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ address: account.address, issued_at: issuedAt, nonce, signature, ...opts.extra }),\n });\n if (!resp.ok) {\n throw new Error(`x402 balance check failed: ${resp.status} ${await resp.text()}`);\n }\n return (await resp.json()) as X402WalletBalance;\n}\n\nconst MISSING_X402 =\n \"x402 mode requires the optional peer deps. Install them with: \" +\n \"npm install @x402/fetch @x402/evm viem \" +\n \"(or the equivalent for pnpm/yarn).\";\n\n/** Build a ready-to-use x402 client from an EVM private key (`0x...`). */\nexport async function x402ClientFromPrivateKey(\n privateKey: `0x${string}` | string,\n): Promise<X402Client> {\n let viem;\n let fetchPkg;\n let evmPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n viem = await import(\"viem/accounts\");\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n // @ts-ignore - optional peer dep, may not be installed\n evmPkg = await import(\"@x402/evm\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n\n const key = privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`;\n const signer = viem.privateKeyToAccount(key as `0x${string}`);\n const client = new fetchPkg.x402Client();\n client.register(\"eip155:*\", new evmPkg.ExactEvmScheme(signer));\n return client;\n}\n\n/** Wrap a fetch with x402 payment handling. */\nexport async function wrapFetchWithX402(\n fetch: FetchLike,\n x402Client: X402Client,\n): Promise<FetchLike> {\n let fetchPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n return fetchPkg.wrapFetchWithPayment(fetch, x402Client);\n}\n","import { BrowserUseError } from \"./errors.js\";\nimport type { FetchLike } from \"./x402.js\";\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Optional custom fetch implementation. May be a sync value or a Promise\n * (for lazy resolution of e.g. x402-wrapped fetch). When set, replaces\n * `globalThis.fetch`. The `X-Browser-Use-API-Key` header is still sent if\n * `apiKey` is non-empty (top-up mode in x402); pass `apiKey: \"\"` to omit.\n */\n fetch?: FetchLike | Promise<FetchLike>;\n}\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly maxRetries: number;\n private readonly timeout: number;\n private readonly fetchPromise: Promise<FetchLike>;\n private readonly useApiKeyHeader: boolean;\n\n constructor(options: HttpClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.maxRetries = options.maxRetries ?? 3;\n this.timeout = options.timeout ?? 30_000;\n this.fetchPromise = Promise.resolve(\n options.fetch ?? ((input, init) => fetch(input, init)),\n );\n // Send the API key header whenever apiKey is non-empty. In x402 mode\n // an empty apiKey means \"accountless\" (wallet is identity); a non-empty\n // apiKey means \"top up the existing key's project\".\n this.useApiKeyHeader = options.apiKey !== \"\";\n }\n\n async request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n query?: Record<string, unknown>;\n signal?: AbortSignal;\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (options?.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {};\n if (this.useApiKeyHeader) {\n headers[\"X-Browser-Use-API-Key\"] = this.apiKey;\n }\n if (options?.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = Math.min(1000 * 2 ** (attempt - 1), 10_000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n const controller = new AbortController();\n const timeoutId = options?.signal\n ? undefined\n : setTimeout(() => controller.abort(), this.timeout);\n\n // Combine user signal with internal timeout when both are present\n const signal = options?.signal ?? controller.signal;\n\n try {\n const fetchImpl = await this.fetchPromise;\n const response = await fetchImpl(url.toString(), {\n method,\n headers,\n body: options?.body !== undefined ? JSON.stringify(options.body) : undefined,\n signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n if (response.status === 204) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n const shouldRetry =\n response.status === 429 &&\n attempt < this.maxRetries;\n\n if (shouldRetry) {\n continue;\n }\n\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n /* ignore parse errors */\n }\n const raw =\n typeof errorBody === \"object\" && errorBody !== null\n ? \"message\" in errorBody\n ? (errorBody as Record<string, unknown>).message\n : \"detail\" in errorBody\n ? (errorBody as Record<string, unknown>).detail\n : undefined\n : undefined;\n const message =\n raw === undefined\n ? `HTTP ${response.status}`\n : typeof raw === \"string\"\n ? raw\n : JSON.stringify(raw);\n throw new BrowserUseError(response.status, message, errorBody);\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n throw new Error(\"Unreachable: retry loop exhausted\");\n }\n\n get<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n post<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"POST\", path, { body, query });\n }\n\n patch<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"PATCH\", path, { body, query });\n }\n\n delete<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"DELETE\", path, { query });\n }\n}\n"],"mappings":"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","names":["fetch"]}
|
|
@@ -10,6 +10,69 @@ var BrowserUseError = class extends Error {
|
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
// src/core/x402.ts
|
|
14
|
+
var X402_BASE_URL_DEFAULT = "https://x402.api.browser-use.com/api/v3";
|
|
15
|
+
var X402_BASE_URL_DEFAULT_V2 = "https://x402.api.browser-use.com/api/v2";
|
|
16
|
+
var X402_BALANCE_BASE_URL_DEFAULT = "https://api.browser-use.com/api/v3";
|
|
17
|
+
function buildWalletAuthMessage(address, issuedAt, nonce) {
|
|
18
|
+
return `Browser Use x402 wallet authentication
|
|
19
|
+
Action: read credit balance
|
|
20
|
+
Wallet: ${address}
|
|
21
|
+
Issued At: ${issuedAt}
|
|
22
|
+
Nonce: ${nonce}`;
|
|
23
|
+
}
|
|
24
|
+
async function getWalletBalance(privateKey, opts = {}) {
|
|
25
|
+
let viem;
|
|
26
|
+
try {
|
|
27
|
+
viem = await Promise.resolve().then(() => _interopRequireWildcard(require("viem/accounts")));
|
|
28
|
+
} catch (e2) {
|
|
29
|
+
throw new Error(MISSING_X402);
|
|
30
|
+
}
|
|
31
|
+
const key = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
32
|
+
const account = viem.privateKeyToAccount(key);
|
|
33
|
+
const issuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
34
|
+
const nonce = crypto.randomUUID().replace(/-/g, "");
|
|
35
|
+
const message = buildWalletAuthMessage(account.address, issuedAt, nonce);
|
|
36
|
+
const signature = await account.signMessage({ message });
|
|
37
|
+
const baseUrl = (_nullishCoalesce(opts.baseUrl, () => ( X402_BALANCE_BASE_URL_DEFAULT))).replace(/\/$/, "");
|
|
38
|
+
const resp = await fetch(`${baseUrl}/x402/balance`, {
|
|
39
|
+
method: "POST",
|
|
40
|
+
headers: { "Content-Type": "application/json" },
|
|
41
|
+
body: JSON.stringify({ address: account.address, issued_at: issuedAt, nonce, signature, ...opts.extra })
|
|
42
|
+
});
|
|
43
|
+
if (!resp.ok) {
|
|
44
|
+
throw new Error(`x402 balance check failed: ${resp.status} ${await resp.text()}`);
|
|
45
|
+
}
|
|
46
|
+
return await resp.json();
|
|
47
|
+
}
|
|
48
|
+
var MISSING_X402 = "x402 mode requires the optional peer deps. Install them with: npm install @x402/fetch @x402/evm viem (or the equivalent for pnpm/yarn).";
|
|
49
|
+
async function x402ClientFromPrivateKey(privateKey) {
|
|
50
|
+
let viem;
|
|
51
|
+
let fetchPkg;
|
|
52
|
+
let evmPkg;
|
|
53
|
+
try {
|
|
54
|
+
viem = await Promise.resolve().then(() => _interopRequireWildcard(require("viem/accounts")));
|
|
55
|
+
fetchPkg = await Promise.resolve().then(() => _interopRequireWildcard(require("@x402/fetch")));
|
|
56
|
+
evmPkg = await Promise.resolve().then(() => _interopRequireWildcard(require("@x402/evm")));
|
|
57
|
+
} catch (e) {
|
|
58
|
+
throw new Error(MISSING_X402);
|
|
59
|
+
}
|
|
60
|
+
const key = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
61
|
+
const signer = viem.privateKeyToAccount(key);
|
|
62
|
+
const client = new fetchPkg.x402Client();
|
|
63
|
+
client.register("eip155:*", new evmPkg.ExactEvmScheme(signer));
|
|
64
|
+
return client;
|
|
65
|
+
}
|
|
66
|
+
async function wrapFetchWithX402(fetch2, x402Client) {
|
|
67
|
+
let fetchPkg;
|
|
68
|
+
try {
|
|
69
|
+
fetchPkg = await Promise.resolve().then(() => _interopRequireWildcard(require("@x402/fetch")));
|
|
70
|
+
} catch (e) {
|
|
71
|
+
throw new Error(MISSING_X402);
|
|
72
|
+
}
|
|
73
|
+
return fetchPkg.wrapFetchWithPayment(fetch2, x402Client);
|
|
74
|
+
}
|
|
75
|
+
|
|
13
76
|
// src/core/http.ts
|
|
14
77
|
var HttpClient = class {
|
|
15
78
|
|
|
@@ -74,7 +137,7 @@ var HttpClient = class {
|
|
|
74
137
|
let errorBody;
|
|
75
138
|
try {
|
|
76
139
|
errorBody = await response.json();
|
|
77
|
-
} catch (
|
|
140
|
+
} catch (e3) {
|
|
78
141
|
}
|
|
79
142
|
const raw = typeof errorBody === "object" && errorBody !== null ? "message" in errorBody ? errorBody.message : "detail" in errorBody ? errorBody.detail : void 0 : void 0;
|
|
80
143
|
const message = raw === void 0 ? `HTTP ${response.status}` : typeof raw === "string" ? raw : JSON.stringify(raw);
|
|
@@ -100,36 +163,6 @@ var HttpClient = class {
|
|
|
100
163
|
}
|
|
101
164
|
};
|
|
102
165
|
|
|
103
|
-
// src/core/x402.ts
|
|
104
|
-
var X402_BASE_URL_DEFAULT = "https://x402.api.browser-use.com/api/v3";
|
|
105
|
-
var X402_BASE_URL_DEFAULT_V2 = "https://x402.api.browser-use.com/api/v2";
|
|
106
|
-
var MISSING_X402 = "x402 mode requires the optional peer deps. Install them with: npm install @x402/fetch @x402/evm viem (or the equivalent for pnpm/yarn).";
|
|
107
|
-
async function x402ClientFromPrivateKey(privateKey) {
|
|
108
|
-
let viem;
|
|
109
|
-
let fetchPkg;
|
|
110
|
-
let evmPkg;
|
|
111
|
-
try {
|
|
112
|
-
viem = await Promise.resolve().then(() => _interopRequireWildcard(require("viem/accounts")));
|
|
113
|
-
fetchPkg = await Promise.resolve().then(() => _interopRequireWildcard(require("@x402/fetch")));
|
|
114
|
-
evmPkg = await Promise.resolve().then(() => _interopRequireWildcard(require("@x402/evm")));
|
|
115
|
-
} catch (e) {
|
|
116
|
-
throw new Error(MISSING_X402);
|
|
117
|
-
}
|
|
118
|
-
const key = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
119
|
-
const signer = viem.privateKeyToAccount(key);
|
|
120
|
-
const client = new fetchPkg.x402Client();
|
|
121
|
-
client.register("eip155:*", new evmPkg.ExactEvmScheme(signer));
|
|
122
|
-
return client;
|
|
123
|
-
}
|
|
124
|
-
async function wrapFetchWithX402(fetch2, x402Client) {
|
|
125
|
-
let fetchPkg;
|
|
126
|
-
try {
|
|
127
|
-
fetchPkg = await Promise.resolve().then(() => _interopRequireWildcard(require("@x402/fetch")));
|
|
128
|
-
} catch (e) {
|
|
129
|
-
throw new Error(MISSING_X402);
|
|
130
|
-
}
|
|
131
|
-
return fetchPkg.wrapFetchWithPayment(fetch2, x402Client);
|
|
132
|
-
}
|
|
133
166
|
|
|
134
167
|
|
|
135
168
|
|
|
@@ -138,5 +171,5 @@ async function wrapFetchWithX402(fetch2, x402Client) {
|
|
|
138
171
|
|
|
139
172
|
|
|
140
173
|
|
|
141
|
-
exports.BrowserUseError = BrowserUseError; exports.HttpClient = HttpClient; exports.X402_BASE_URL_DEFAULT = X402_BASE_URL_DEFAULT; exports.X402_BASE_URL_DEFAULT_V2 = X402_BASE_URL_DEFAULT_V2; exports.x402ClientFromPrivateKey = x402ClientFromPrivateKey; exports.wrapFetchWithX402 = wrapFetchWithX402;
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
174
|
+
exports.BrowserUseError = BrowserUseError; exports.HttpClient = HttpClient; exports.X402_BASE_URL_DEFAULT = X402_BASE_URL_DEFAULT; exports.X402_BASE_URL_DEFAULT_V2 = X402_BASE_URL_DEFAULT_V2; exports.getWalletBalance = getWalletBalance; exports.x402ClientFromPrivateKey = x402ClientFromPrivateKey; exports.wrapFetchWithX402 = wrapFetchWithX402;
|
|
175
|
+
//# sourceMappingURL=chunk-QMK4AUMH.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/chunk-QMK4AUMH.cjs","../src/core/errors.ts","../src/core/x402.ts","../src/core/http.ts"],"names":[],"mappings":"AAAA;ACAO,IAAM,gBAAA,EAAN,MAAA,QAA8B,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EAET,WAAA,CAAY,UAAA,EAAoB,OAAA,EAAiB,MAAA,EAAkB;AACjE,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,KAAA,EAAO,iBAAA;AACZ,IAAA,IAAA,CAAK,WAAA,EAAa,UAAA;AAClB,IAAA,IAAA,CAAK,OAAA,EAAS,MAAA;AAAA,EAChB;AACF,CAAA;ADCA;AACA;AEMO,IAAM,sBAAA,EAAwB,yCAAA;AAC9B,IAAM,yBAAA,EAA2B,yCAAA;AACjC,IAAM,8BAAA,EAAgC,oCAAA;AAS7C,SAAS,sBAAA,CAAuB,OAAA,EAAiB,QAAA,EAAkB,KAAA,EAAuB;AACxF,EAAA,OACE,CAAA;AAAA;AAAA,QAAA,EAEW,OAAO,CAAA;AAAA,WAAA,EACJ,QAAQ,CAAA;AAAA,OAAA,EACZ,KAAK,CAAA,CAAA;AAEnB;AASsB;AAIhB,EAAA;AACA,EAAA;AAEK,IAAA;AACD,EAAA;AACI,IAAA;AACZ,EAAA;AACY,EAAA;AACN,EAAA;AAEA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AAEA,EAAA;AACO,EAAA;AACH,IAAA;AACG,IAAA;AACA,IAAA;AACZ,EAAA;AACS,EAAA;AACE,IAAA;AACZ,EAAA;AACc,EAAA;AAChB;AAEM;AAMgB;AAGhB,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AAEK,IAAA;AAEI,IAAA;AAEF,IAAA;AACC,EAAA;AACA,IAAA;AACZ,EAAA;AAEY,EAAA;AACN,EAAA;AACA,EAAA;AACC,EAAA;AACA,EAAA;AACT;AAGsB;AAIhB,EAAA;AACA,EAAA;AAES,IAAA;AACD,EAAA;AACA,IAAA;AACZ,EAAA;AACO,EAAA;AACT;AF9Ce;AACA;AG1DF;AACM,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AAEL,EAAA;AACL,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACK,uBAAA;AACV,IAAA;AAIK,IAAA;AACP,EAAA;AAEM,EAAA;AASE,IAAA;AACF,IAAA;AACF,MAAA;AACM,QAAA;AACE,UAAA;AACN,QAAA;AACF,MAAA;AACF,IAAA;AAEM,IAAA;AACG,IAAA;AACC,MAAA;AACV,IAAA;AACI,IAAA;AACM,MAAA;AACV,IAAA;AAES,IAAA;AACH,MAAA;AACI,QAAA;AACA,QAAA;AACR,MAAA;AAEM,MAAA;AACA,MAAA;AAKA,MAAA;AAEF,MAAA;AACI,QAAA;AACA,QAAA;AACJ,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACD,QAAA;AAED,QAAA;AAEI,QAAA;AACE,UAAA;AACF,YAAA;AACF,UAAA;AACA,UAAA;AACF,QAAA;AAEM,QAAA;AAIF,QAAA;AACF,UAAA;AACF,QAAA;AAEI,QAAA;AACA,QAAA;AACF,UAAA;AACF,QAAA;AAEA,QAAA;AACM,QAAA;AAQA,QAAA;AAMA,QAAA;AACC,MAAA;AACP,QAAA;AACM,QAAA;AACR,MAAA;AACF,IAAA;AAEU,IAAA;AACZ,EAAA;AAEqB,EAAA;AACZ,IAAA;AACT,EAAA;AAEsB,EAAA;AACb,IAAA;AACT,EAAA;AAEuB,EAAA;AACd,IAAA;AACT,EAAA;AAEwB,EAAA;AACf,IAAA;AACT,EAAA;AACF;AHce;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/chunk-QMK4AUMH.cjs","sourcesContent":[null,"export class BrowserUseError extends Error {\n readonly statusCode: number;\n readonly detail: unknown;\n\n constructor(statusCode: number, message: string, detail?: unknown) {\n super(message);\n this.name = \"BrowserUseError\";\n this.statusCode = statusCode;\n this.detail = detail;\n }\n}\n","/**\n * Helpers for the optional x402 (pay-per-request) integration.\n *\n * x402 is an HTTP payment protocol: instead of an API key, requests are\n * authenticated by signing a small USDC payment. See the docs at\n * `cloud/guides/x402` and https://www.x402.org for details.\n *\n * The peer deps `@x402/fetch`, `@x402/evm`, and `viem` are optional. They are\n * imported lazily so users who only use API-key auth never pay the cost.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type X402Client = any;\nexport type FetchLike = (\n input: RequestInfo | URL,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport const X402_BASE_URL_DEFAULT = \"https://x402.api.browser-use.com/api/v3\";\nexport const X402_BASE_URL_DEFAULT_V2 = \"https://x402.api.browser-use.com/api/v2\";\nexport const X402_BALANCE_BASE_URL_DEFAULT = \"https://api.browser-use.com/api/v3\";\n\nexport interface X402WalletBalance {\n wallet: string;\n project_id: string;\n total_credits_usd: number;\n additional_credits_usd: number;\n}\n\nfunction buildWalletAuthMessage(address: string, issuedAt: string, nonce: string): string {\n return (\n \"Browser Use x402 wallet authentication\\n\" +\n \"Action: read credit balance\\n\" +\n `Wallet: ${address}\\n` +\n `Issued At: ${issuedAt}\\n` +\n `Nonce: ${nonce}`\n );\n}\n\n/**\n * Read a wallet-derived project's credit balance\n *\n * Authenticates with an off-chain wallet signature (EIP-191): signs a\n * message proving control of the address; the server resolves the wallet to its\n * project and returns the balance\n */\nexport async function getWalletBalance(\n privateKey: `0x${string}` | string,\n opts: { baseUrl?: string; extra?: Record<string, unknown> } = {},\n): Promise<X402WalletBalance> {\n let viem;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n viem = await import(\"viem/accounts\");\n } catch {\n throw new Error(MISSING_X402);\n }\n const key = privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`;\n const account = viem.privateKeyToAccount(key as `0x${string}`);\n\n const issuedAt = new Date().toISOString();\n const nonce = crypto.randomUUID().replace(/-/g, \"\");\n const message = buildWalletAuthMessage(account.address, issuedAt, nonce);\n const signature = await account.signMessage({ message });\n\n const baseUrl = (opts.baseUrl ?? X402_BALANCE_BASE_URL_DEFAULT).replace(/\\/$/, \"\");\n const resp = await fetch(`${baseUrl}/x402/balance`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ address: account.address, issued_at: issuedAt, nonce, signature, ...opts.extra }),\n });\n if (!resp.ok) {\n throw new Error(`x402 balance check failed: ${resp.status} ${await resp.text()}`);\n }\n return (await resp.json()) as X402WalletBalance;\n}\n\nconst MISSING_X402 =\n \"x402 mode requires the optional peer deps. Install them with: \" +\n \"npm install @x402/fetch @x402/evm viem \" +\n \"(or the equivalent for pnpm/yarn).\";\n\n/** Build a ready-to-use x402 client from an EVM private key (`0x...`). */\nexport async function x402ClientFromPrivateKey(\n privateKey: `0x${string}` | string,\n): Promise<X402Client> {\n let viem;\n let fetchPkg;\n let evmPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n viem = await import(\"viem/accounts\");\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n // @ts-ignore - optional peer dep, may not be installed\n evmPkg = await import(\"@x402/evm\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n\n const key = privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`;\n const signer = viem.privateKeyToAccount(key as `0x${string}`);\n const client = new fetchPkg.x402Client();\n client.register(\"eip155:*\", new evmPkg.ExactEvmScheme(signer));\n return client;\n}\n\n/** Wrap a fetch with x402 payment handling. */\nexport async function wrapFetchWithX402(\n fetch: FetchLike,\n x402Client: X402Client,\n): Promise<FetchLike> {\n let fetchPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n return fetchPkg.wrapFetchWithPayment(fetch, x402Client);\n}\n","import { BrowserUseError } from \"./errors.js\";\nimport type { FetchLike } from \"./x402.js\";\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Optional custom fetch implementation. May be a sync value or a Promise\n * (for lazy resolution of e.g. x402-wrapped fetch). When set, replaces\n * `globalThis.fetch`. The `X-Browser-Use-API-Key` header is still sent if\n * `apiKey` is non-empty (top-up mode in x402); pass `apiKey: \"\"` to omit.\n */\n fetch?: FetchLike | Promise<FetchLike>;\n}\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly maxRetries: number;\n private readonly timeout: number;\n private readonly fetchPromise: Promise<FetchLike>;\n private readonly useApiKeyHeader: boolean;\n\n constructor(options: HttpClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.maxRetries = options.maxRetries ?? 3;\n this.timeout = options.timeout ?? 30_000;\n this.fetchPromise = Promise.resolve(\n options.fetch ?? ((input, init) => fetch(input, init)),\n );\n // Send the API key header whenever apiKey is non-empty. In x402 mode\n // an empty apiKey means \"accountless\" (wallet is identity); a non-empty\n // apiKey means \"top up the existing key's project\".\n this.useApiKeyHeader = options.apiKey !== \"\";\n }\n\n async request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n query?: Record<string, unknown>;\n signal?: AbortSignal;\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (options?.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {};\n if (this.useApiKeyHeader) {\n headers[\"X-Browser-Use-API-Key\"] = this.apiKey;\n }\n if (options?.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = Math.min(1000 * 2 ** (attempt - 1), 10_000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n const controller = new AbortController();\n const timeoutId = options?.signal\n ? undefined\n : setTimeout(() => controller.abort(), this.timeout);\n\n // Combine user signal with internal timeout when both are present\n const signal = options?.signal ?? controller.signal;\n\n try {\n const fetchImpl = await this.fetchPromise;\n const response = await fetchImpl(url.toString(), {\n method,\n headers,\n body: options?.body !== undefined ? JSON.stringify(options.body) : undefined,\n signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n if (response.status === 204) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n const shouldRetry =\n response.status === 429 &&\n attempt < this.maxRetries;\n\n if (shouldRetry) {\n continue;\n }\n\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n /* ignore parse errors */\n }\n const raw =\n typeof errorBody === \"object\" && errorBody !== null\n ? \"message\" in errorBody\n ? (errorBody as Record<string, unknown>).message\n : \"detail\" in errorBody\n ? (errorBody as Record<string, unknown>).detail\n : undefined\n : undefined;\n const message =\n raw === undefined\n ? `HTTP ${response.status}`\n : typeof raw === \"string\"\n ? raw\n : JSON.stringify(raw);\n throw new BrowserUseError(response.status, message, errorBody);\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n throw new Error(\"Unreachable: retry loop exhausted\");\n }\n\n get<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n post<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"POST\", path, { body, query });\n }\n\n patch<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"PATCH\", path, { body, query });\n }\n\n delete<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"DELETE\", path, { query });\n }\n}\n"]}
|
|
@@ -10,6 +10,23 @@
|
|
|
10
10
|
*/
|
|
11
11
|
type X402Client = any;
|
|
12
12
|
type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
13
|
+
interface X402WalletBalance {
|
|
14
|
+
wallet: string;
|
|
15
|
+
project_id: string;
|
|
16
|
+
total_credits_usd: number;
|
|
17
|
+
additional_credits_usd: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Read a wallet-derived project's credit balance
|
|
21
|
+
*
|
|
22
|
+
* Authenticates with an off-chain wallet signature (EIP-191): signs a
|
|
23
|
+
* message proving control of the address; the server resolves the wallet to its
|
|
24
|
+
* project and returns the balance
|
|
25
|
+
*/
|
|
26
|
+
declare function getWalletBalance(privateKey: `0x${string}` | string, opts?: {
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
extra?: Record<string, unknown>;
|
|
29
|
+
}): Promise<X402WalletBalance>;
|
|
13
30
|
|
|
14
31
|
interface HttpClientOptions {
|
|
15
32
|
apiKey: string;
|
|
@@ -49,4 +66,4 @@ declare class BrowserUseError extends Error {
|
|
|
49
66
|
constructor(statusCode: number, message: string, detail?: unknown);
|
|
50
67
|
}
|
|
51
68
|
|
|
52
|
-
export { BrowserUseError as B, HttpClient as H, type X402Client as X };
|
|
69
|
+
export { BrowserUseError as B, HttpClient as H, type X402Client as X, type X402WalletBalance as a, getWalletBalance as g };
|
|
@@ -10,6 +10,23 @@
|
|
|
10
10
|
*/
|
|
11
11
|
type X402Client = any;
|
|
12
12
|
type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
13
|
+
interface X402WalletBalance {
|
|
14
|
+
wallet: string;
|
|
15
|
+
project_id: string;
|
|
16
|
+
total_credits_usd: number;
|
|
17
|
+
additional_credits_usd: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Read a wallet-derived project's credit balance
|
|
21
|
+
*
|
|
22
|
+
* Authenticates with an off-chain wallet signature (EIP-191): signs a
|
|
23
|
+
* message proving control of the address; the server resolves the wallet to its
|
|
24
|
+
* project and returns the balance
|
|
25
|
+
*/
|
|
26
|
+
declare function getWalletBalance(privateKey: `0x${string}` | string, opts?: {
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
extra?: Record<string, unknown>;
|
|
29
|
+
}): Promise<X402WalletBalance>;
|
|
13
30
|
|
|
14
31
|
interface HttpClientOptions {
|
|
15
32
|
apiKey: string;
|
|
@@ -49,4 +66,4 @@ declare class BrowserUseError extends Error {
|
|
|
49
66
|
constructor(statusCode: number, message: string, detail?: unknown);
|
|
50
67
|
}
|
|
51
68
|
|
|
52
|
-
export { BrowserUseError as B, HttpClient as H, type X402Client as X };
|
|
69
|
+
export { BrowserUseError as B, HttpClient as H, type X402Client as X, type X402WalletBalance as a, getWalletBalance as g };
|
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkQMK4AUMHcjs = require('./chunk-QMK4AUMH.cjs');
|
|
8
8
|
|
|
9
9
|
// src/v2/client.ts
|
|
10
10
|
var _zod = require('zod');
|
|
@@ -405,14 +405,14 @@ var BrowserUse = class {
|
|
|
405
405
|
if (options.x402 || x402PrivateKey) {
|
|
406
406
|
const topupKey = _nullishCoalesce(_nullishCoalesce(options.apiKey, () => ( process.env.BROWSER_USE_API_KEY)), () => ( ""));
|
|
407
407
|
const fetchPromise = (async () => {
|
|
408
|
-
const x402Client = await _asyncNullishCoalesce(options.x402, async () => ( await
|
|
409
|
-
return
|
|
408
|
+
const x402Client = await _asyncNullishCoalesce(options.x402, async () => ( await _chunkQMK4AUMHcjs.x402ClientFromPrivateKey.call(void 0, x402PrivateKey)));
|
|
409
|
+
return _chunkQMK4AUMHcjs.wrapFetchWithX402.call(void 0, globalThis.fetch, x402Client);
|
|
410
410
|
})();
|
|
411
411
|
fetchPromise.catch(() => {
|
|
412
412
|
});
|
|
413
|
-
this.http = new (0,
|
|
413
|
+
this.http = new (0, _chunkQMK4AUMHcjs.HttpClient)({
|
|
414
414
|
apiKey: topupKey,
|
|
415
|
-
baseUrl: _nullishCoalesce(options.baseUrl, () => (
|
|
415
|
+
baseUrl: _nullishCoalesce(options.baseUrl, () => ( _chunkQMK4AUMHcjs.X402_BASE_URL_DEFAULT_V2)),
|
|
416
416
|
maxRetries: options.maxRetries,
|
|
417
417
|
timeout: options.timeout,
|
|
418
418
|
fetch: fetchPromise
|
|
@@ -424,7 +424,7 @@ var BrowserUse = class {
|
|
|
424
424
|
"No credentials provided. Pass apiKey / set BROWSER_USE_API_KEY, or pass x402PrivateKey / set BROWSER_USE_X402_PRIVATE_KEY for pay-per-request access via USDC."
|
|
425
425
|
);
|
|
426
426
|
}
|
|
427
|
-
this.http = new (0,
|
|
427
|
+
this.http = new (0, _chunkQMK4AUMHcjs.HttpClient)({
|
|
428
428
|
apiKey,
|
|
429
429
|
baseUrl: _nullishCoalesce(options.baseUrl, () => ( DEFAULT_BASE_URL)),
|
|
430
430
|
maxRetries: options.maxRetries,
|
|
@@ -462,5 +462,5 @@ var BrowserUse = class {
|
|
|
462
462
|
|
|
463
463
|
|
|
464
464
|
|
|
465
|
-
exports.Billing = Billing; exports.BrowserUse = BrowserUse; exports.BrowserUseError =
|
|
465
|
+
exports.Billing = Billing; exports.BrowserUse = BrowserUse; exports.BrowserUseError = _chunkQMK4AUMHcjs.BrowserUseError; exports.Browsers = Browsers; exports.Files = Files; exports.Marketplace = Marketplace; exports.Profiles = Profiles; exports.Sessions = Sessions; exports.Skills = Skills; exports.TaskRun = TaskRun; exports.Tasks = Tasks;
|
|
466
466
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { H as HttpClient, X as X402Client } from './errors-
|
|
3
|
-
export { B as BrowserUseError } from './errors-
|
|
2
|
+
import { H as HttpClient, X as X402Client } from './errors-DaHgFhIQ.cjs';
|
|
3
|
+
export { B as BrowserUseError } from './errors-DaHgFhIQ.cjs';
|
|
4
4
|
|
|
5
5
|
interface components {
|
|
6
6
|
schemas: {
|
|
@@ -352,7 +352,7 @@ interface components {
|
|
|
352
352
|
proxyCountryCode: components["schemas"]["ProxyCountryCode"] | null;
|
|
353
353
|
/**
|
|
354
354
|
* Timeout
|
|
355
|
-
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours).
|
|
355
|
+
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours). Browser sessions are charged $0.02/hour.
|
|
356
356
|
* @default 60
|
|
357
357
|
*/
|
|
358
358
|
timeout: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { H as HttpClient, X as X402Client } from './errors-
|
|
3
|
-
export { B as BrowserUseError } from './errors-
|
|
2
|
+
import { H as HttpClient, X as X402Client } from './errors-DaHgFhIQ.js';
|
|
3
|
+
export { B as BrowserUseError } from './errors-DaHgFhIQ.js';
|
|
4
4
|
|
|
5
5
|
interface components {
|
|
6
6
|
schemas: {
|
|
@@ -352,7 +352,7 @@ interface components {
|
|
|
352
352
|
proxyCountryCode: components["schemas"]["ProxyCountryCode"] | null;
|
|
353
353
|
/**
|
|
354
354
|
* Timeout
|
|
355
|
-
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours).
|
|
355
|
+
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours). Browser sessions are charged $0.02/hour.
|
|
356
356
|
* @default 60
|
|
357
357
|
*/
|
|
358
358
|
timeout: number;
|
package/dist/index.js
CHANGED
package/dist/v3.cjs
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
var _chunkQMK4AUMHcjs = require('./chunk-QMK4AUMH.cjs');
|
|
8
9
|
|
|
9
10
|
// src/v3/client.ts
|
|
10
11
|
var _zod = require('zod');
|
|
@@ -431,14 +432,14 @@ var BrowserUse = class {
|
|
|
431
432
|
if (options.x402 || x402PrivateKey) {
|
|
432
433
|
const topupKey = _nullishCoalesce(_nullishCoalesce(options.apiKey, () => ( process.env.BROWSER_USE_API_KEY)), () => ( ""));
|
|
433
434
|
const fetchPromise = (async () => {
|
|
434
|
-
const x402Client = await _asyncNullishCoalesce(options.x402, async () => ( await
|
|
435
|
-
return
|
|
435
|
+
const x402Client = await _asyncNullishCoalesce(options.x402, async () => ( await _chunkQMK4AUMHcjs.x402ClientFromPrivateKey.call(void 0, x402PrivateKey)));
|
|
436
|
+
return _chunkQMK4AUMHcjs.wrapFetchWithX402.call(void 0, globalThis.fetch, x402Client);
|
|
436
437
|
})();
|
|
437
438
|
fetchPromise.catch(() => {
|
|
438
439
|
});
|
|
439
|
-
this.http = new (0,
|
|
440
|
+
this.http = new (0, _chunkQMK4AUMHcjs.HttpClient)({
|
|
440
441
|
apiKey: topupKey,
|
|
441
|
-
baseUrl: _nullishCoalesce(options.baseUrl, () => (
|
|
442
|
+
baseUrl: _nullishCoalesce(options.baseUrl, () => ( _chunkQMK4AUMHcjs.X402_BASE_URL_DEFAULT)),
|
|
442
443
|
maxRetries: options.maxRetries,
|
|
443
444
|
timeout: options.timeout,
|
|
444
445
|
fetch: fetchPromise
|
|
@@ -450,7 +451,7 @@ var BrowserUse = class {
|
|
|
450
451
|
"No credentials provided. Pass apiKey / set BROWSER_USE_API_KEY, or pass x402PrivateKey / set BROWSER_USE_X402_PRIVATE_KEY for pay-per-request access via USDC."
|
|
451
452
|
);
|
|
452
453
|
}
|
|
453
|
-
this.http = new (0,
|
|
454
|
+
this.http = new (0, _chunkQMK4AUMHcjs.HttpClient)({
|
|
454
455
|
apiKey,
|
|
455
456
|
baseUrl: _nullishCoalesce(options.baseUrl, () => ( DEFAULT_BASE_URL)),
|
|
456
457
|
maxRetries: options.maxRetries,
|
|
@@ -509,5 +510,6 @@ var BrowserUse = class {
|
|
|
509
510
|
|
|
510
511
|
|
|
511
512
|
|
|
512
|
-
|
|
513
|
+
|
|
514
|
+
exports.Billing = Billing; exports.BrowserUse = BrowserUse; exports.BrowserUseError = _chunkQMK4AUMHcjs.BrowserUseError; exports.Browsers = Browsers; exports.Profiles = Profiles; exports.SessionRun = SessionRun; exports.Sessions = Sessions; exports.Workspaces = Workspaces; exports.getWalletBalance = _chunkQMK4AUMHcjs.getWalletBalance;
|
|
513
515
|
//# sourceMappingURL=v3.cjs.map
|
package/dist/v3.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/v3.cjs","../src/v3/client.ts","../src/v3/resources/billing.ts","../src/v3/resources/browsers.ts","../src/v3/resources/profiles.ts","../src/v3/resources/sessions.ts","../src/v3/resources/workspaces.ts","../src/v3/helpers.ts"],"names":[],"mappings":"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","file":"/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/v3.cjs","sourcesContent":[null,"import { z } from \"zod\";\nimport { HttpClient } from \"../core/http.js\";\nimport {\n X402_BASE_URL_DEFAULT,\n type X402Client,\n wrapFetchWithX402,\n x402ClientFromPrivateKey,\n} from \"../core/x402.js\";\nimport { Billing } from \"./resources/billing.js\";\nimport { Browsers } from \"./resources/browsers.js\";\nimport { Profiles } from \"./resources/profiles.js\";\nimport { Sessions } from \"./resources/sessions.js\";\nimport { Workspaces } from \"./resources/workspaces.js\";\nimport { SessionRun } from \"./helpers.js\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { RunOptions } from \"./helpers.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n\nconst DEFAULT_BASE_URL = \"https://api.browser-use.com/api/v3\";\n\nexport interface BrowserUseOptions {\n apiKey?: string;\n baseUrl?: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Use your own LLM API key configured in Browser Use project settings for v3 agent runs.\n */\n useOwnKey?: boolean;\n /**\n * Pre-built x402 client (advanced — for custom signers / multi-network).\n * If set, the SDK uses pay-per-request authentication via USDC instead of\n * an API key. Requires the optional peer deps `@x402/fetch`, `@x402/evm`,\n * and `viem`.\n */\n x402?: X402Client;\n /**\n * EVM wallet private key for x402 mode. Equivalent to building an x402\n * client from this key and passing it as `x402`. Falls back to\n * `BROWSER_USE_X402_PRIVATE_KEY`.\n */\n x402PrivateKey?: string;\n}\n\nexport type RunSessionOptions = Partial<Omit<RunTaskRequest, \"task\">> &\n RunOptions & { schema?: z.ZodType };\n\nexport class BrowserUse {\n readonly billing: Billing;\n readonly browsers: Browsers;\n readonly profiles: Profiles;\n readonly sessions: Sessions;\n readonly workspaces: Workspaces;\n\n private readonly http: HttpClient;\n\n constructor(options: BrowserUseOptions = {}) {\n const x402PrivateKey =\n options.x402PrivateKey ?? process.env.BROWSER_USE_X402_PRIVATE_KEY;\n\n if (options.x402 || x402PrivateKey) {\n // x402 mode — defer x402 client + wrapped fetch resolution to first request.\n // If apiKey is also set, it's forwarded as a header so the backend\n // credits the API key's project (top-up mode) instead of one keyed\n // to the wallet.\n const topupKey = options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n const fetchPromise = (async () => {\n const x402Client = options.x402 ?? (await x402ClientFromPrivateKey(x402PrivateKey!));\n return wrapFetchWithX402(globalThis.fetch, x402Client);\n })();\n // Suppress unhandled-rejection warnings if the user constructs the client\n // but never makes a request\n fetchPromise.catch(() => {});\n this.http = new HttpClient({\n apiKey: topupKey,\n baseUrl: options.baseUrl ?? X402_BASE_URL_DEFAULT,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n fetch: fetchPromise,\n });\n } else {\n const apiKey =\n options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"No credentials provided. Pass apiKey / set BROWSER_USE_API_KEY, \" +\n \"or pass x402PrivateKey / set BROWSER_USE_X402_PRIVATE_KEY for \" +\n \"pay-per-request access via USDC.\",\n );\n }\n this.http = new HttpClient({\n apiKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n });\n }\n\n this.billing = new Billing(this.http);\n this.browsers = new Browsers(this.http);\n this.profiles = new Profiles(this.http);\n this.sessions = new Sessions(this.http, { useOwnKey: options.useOwnKey });\n this.workspaces = new Workspaces(this.http);\n }\n\n /**\n * Create a session and run a task. `await` the result for a typed SessionResult.\n *\n * ```ts\n * // Simple — just get the output\n * const result = await client.run(\"Find the top HN post\");\n * console.log(result.output);\n *\n * // Structured output (Zod)\n * const result = await client.run(\"Find product info\", { schema: ProductSchema });\n * console.log(result.output.name); // fully typed\n * ```\n */\n run(task: string, options?: Omit<RunSessionOptions, \"schema\">): SessionRun<string>;\n run<T extends z.ZodType>(task: string, options: RunSessionOptions & { schema: T }): SessionRun<z.output<T>>;\n run(task: string, options?: RunSessionOptions): SessionRun<any> {\n const { schema, timeout, interval, ...rest } = options ?? {};\n const body = { task, ...rest } as RunTaskRequest;\n if (body.proxyCountryCode) {\n body.proxyCountryCode = body.proxyCountryCode.toLowerCase() as any;\n }\n if (schema) {\n if (typeof schema !== \"object\" || !(\"_zod\" in schema || \"_def\" in schema)) {\n throw new Error(\n \"schema must be a Zod schema (e.g. z.object({...})). \" +\n \"Make sure you are using Zod v4: npm install zod@4\"\n );\n }\n body.outputSchema = z.toJSONSchema(schema) as Record<string, unknown>;\n }\n // Auto keep_alive when dispatching to an existing session\n if (body.sessionId && body.keepAlive === undefined) {\n body.keepAlive = true;\n }\n // For follow-up runs on an existing session, snapshot the latest message\n // cursor before creating the new task so the iterator skips old messages.\n if (body.sessionId) {\n const sid = body.sessionId;\n const sessions = this.sessions;\n let startCursor: string | undefined;\n const promise = sessions\n .messages(sid, { limit: 1 })\n .then((resp) => {\n const last = resp.messages[resp.messages.length - 1];\n startCursor = last?.id;\n })\n .then(() => sessions.create(body));\n // startCursor is set before createPromise resolves, so the iterator\n // (which awaits _ensureSessionId first) will see the correct value.\n return new SessionRun(promise, this.sessions, schema, {\n timeout,\n interval,\n get _startCursor() { return startCursor; },\n });\n }\n const promise = this.sessions.create(body);\n return new SessionRun(promise, this.sessions, schema, { timeout, interval });\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype AccountView = components[\"schemas\"][\"AccountView\"];\n\nexport class Billing {\n constructor(private readonly http: HttpClient) {}\n\n /** Get account billing information. */\n account(): Promise<AccountView> {\n return this.http.get<AccountView>(\"/billing/account\");\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype CreateBrowserSessionRequest = components[\"schemas\"][\"CreateBrowserSessionRequest\"];\ntype BrowserSessionItemView = components[\"schemas\"][\"BrowserSessionItemView\"];\ntype BrowserSessionView = components[\"schemas\"][\"BrowserSessionView\"];\ntype BrowserSessionListResponse = components[\"schemas\"][\"BrowserSessionListResponse\"];\ntype UpdateBrowserSessionRequest = components[\"schemas\"][\"UpdateBrowserSessionRequest\"];\ntype BrowserDownloadListResponse = components[\"schemas\"][\"BrowserDownloadListResponse\"];\n\nexport interface BrowserListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface BrowserDownloadsParams {\n limit?: number;\n cursor?: string;\n includeUrls?: boolean;\n}\n\nexport class Browsers {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a standalone browser session. */\n create(body: Partial<CreateBrowserSessionRequest> = {}): Promise<BrowserSessionItemView> {\n return this.http.post<BrowserSessionItemView>(\"/browsers\", body);\n }\n\n /** List browser sessions for the authenticated project. */\n list(params?: BrowserListParams): Promise<BrowserSessionListResponse> {\n return this.http.get<BrowserSessionListResponse>(\"/browsers\", params as Record<string, unknown>);\n }\n\n /** Get browser session details. */\n get(sessionId: string): Promise<BrowserSessionView> {\n return this.http.get<BrowserSessionView>(`/browsers/${sessionId}`);\n }\n\n /** Update a browser session (e.g. stop it). */\n update(sessionId: string, body: UpdateBrowserSessionRequest): Promise<BrowserSessionView> {\n return this.http.patch<BrowserSessionView>(`/browsers/${sessionId}`, body);\n }\n\n /** Stop a browser session. Convenience wrapper around update. */\n stop(sessionId: string): Promise<BrowserSessionView> {\n return this.update(sessionId, { action: \"stop\" });\n }\n\n /** List files the browser downloaded to S3 during the session. */\n downloads(sessionId: string, params?: BrowserDownloadsParams): Promise<BrowserDownloadListResponse> {\n return this.http.get<BrowserDownloadListResponse>(\n `/browsers/${sessionId}/downloads`,\n params as Record<string, unknown>,\n );\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype ProfileView = components[\"schemas\"][\"ProfileView\"];\ntype ProfileListResponse = components[\"schemas\"][\"ProfileListResponse\"];\ntype ProfileCreateRequest = components[\"schemas\"][\"ProfileCreateRequest\"];\ntype ProfileUpdateRequest = components[\"schemas\"][\"ProfileUpdateRequest\"];\n\nexport interface ProfileListParams {\n query?: string;\n page?: number;\n page_size?: number;\n}\n\nexport class Profiles {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a browser profile. */\n create(body?: ProfileCreateRequest): Promise<ProfileView> {\n return this.http.post<ProfileView>(\"/profiles\", body);\n }\n\n /** List profiles for the authenticated project. */\n list(params?: ProfileListParams): Promise<ProfileListResponse> {\n return this.http.get<ProfileListResponse>(\"/profiles\", params as Record<string, unknown>);\n }\n\n /** Get profile details. */\n get(profileId: string): Promise<ProfileView> {\n return this.http.get<ProfileView>(`/profiles/${profileId}`);\n }\n\n /** Update a profile. */\n update(profileId: string, body: ProfileUpdateRequest): Promise<ProfileView> {\n return this.http.patch<ProfileView>(`/profiles/${profileId}`, body);\n }\n\n /** Delete a profile. */\n delete(profileId: string): Promise<void> {\n return this.http.delete<void>(`/profiles/${profileId}`);\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n/** All fields optional — omit `task` to create an idle session. */\nexport type CreateSessionBody = Partial<RunTaskRequest>;\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype SessionListResponse = components[\"schemas\"][\"SessionListResponse\"];\ntype StopSessionRequest = components[\"schemas\"][\"StopSessionRequest\"];\ntype MessageListResponse = components[\"schemas\"][\"MessageListResponse\"];\n\nexport interface SessionListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface SessionMessagesParams {\n after?: string | null;\n before?: string | null;\n limit?: number;\n}\n\nexport interface SessionsOptions {\n useOwnKey?: boolean;\n}\n\nexport class Sessions {\n constructor(\n private readonly http: HttpClient,\n private readonly options: SessionsOptions = {},\n ) {}\n\n /** Create a session and optionally dispatch a task. */\n create(body?: CreateSessionBody): Promise<SessionResponse> {\n const requestBody = { ...(body ?? {}) };\n if (\n this.options.useOwnKey !== undefined &&\n requestBody.useOwnKey === undefined\n ) {\n requestBody.useOwnKey = this.options.useOwnKey;\n }\n return this.http.post<SessionResponse>(\"/sessions\", requestBody);\n }\n\n /** List sessions for the authenticated project. */\n list(params?: SessionListParams): Promise<SessionListResponse> {\n return this.http.get<SessionListResponse>(\"/sessions\", params as Record<string, unknown>);\n }\n\n /** Get session details. */\n get(sessionId: string): Promise<SessionResponse> {\n return this.http.get<SessionResponse>(`/sessions/${sessionId}`);\n }\n\n /** Stop a session or the running task. */\n stop(sessionId: string, body?: StopSessionRequest): Promise<SessionResponse> {\n return this.http.post<SessionResponse>(`/sessions/${sessionId}/stop`, body);\n }\n\n /** Soft-delete a session. */\n delete(sessionId: string): Promise<void> {\n return this.http.delete<void>(`/sessions/${sessionId}`);\n }\n\n /** List messages for a session with cursor-based pagination. */\n messages(sessionId: string, params?: SessionMessagesParams): Promise<MessageListResponse> {\n return this.http.get<MessageListResponse>(\n `/sessions/${sessionId}/messages`,\n params as Record<string, unknown>,\n );\n }\n\n /**\n * Poll until recording URLs are available. Returns presigned MP4 URLs.\n *\n * Returns an empty array if no recording was produced (e.g. the agent\n * answered without opening a browser, or recording was not enabled).\n */\n async waitForRecording(\n sessionId: string,\n options?: { timeout?: number; interval?: number },\n ): Promise<string[]> {\n const timeout = options?.timeout ?? 15_000;\n const interval = options?.interval ?? 2_000;\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const session = await this.get(sessionId);\n if (session.recordingUrls?.length) return session.recordingUrls;\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(interval, remaining)));\n }\n return [];\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, statSync } from \"fs\";\nimport { basename, dirname, extname, join, resolve } from \"path\";\nimport type { HttpClient } from \"../../core/http.js\";\n\nfunction safeJoin(base: string, untrusted: string): string {\n const baseResolved = resolve(base) + \"/\";\n const resolved = resolve(base, untrusted);\n if (resolved !== resolve(base) && !resolved.startsWith(baseResolved)) {\n throw new Error(`Path traversal detected: ${untrusted}`);\n }\n return resolved;\n}\n\nconst MIME_TYPES: Record<string, string> = {\n \".csv\": \"text/csv\",\n \".json\": \"application/json\",\n \".txt\": \"text/plain\",\n \".md\": \"text/markdown\",\n \".html\": \"text/html\",\n \".xml\": \"application/xml\",\n \".yaml\": \"application/yaml\",\n \".yml\": \"application/yaml\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".zip\": \"application/zip\",\n \".gz\": \"application/gzip\",\n \".tar\": \"application/x-tar\",\n \".xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \".xls\": \"application/vnd.ms-excel\",\n \".docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".doc\": \"application/msword\",\n \".pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n};\n\nfunction guessContentType(path: string): string {\n return MIME_TYPES[extname(path).toLowerCase()] ?? \"application/octet-stream\";\n}\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype WorkspaceView = components[\"schemas\"][\"WorkspaceView\"];\ntype WorkspaceListResponse = components[\"schemas\"][\"WorkspaceListResponse\"];\ntype WorkspaceCreateRequest = components[\"schemas\"][\"WorkspaceCreateRequest\"];\ntype WorkspaceUpdateRequest = components[\"schemas\"][\"WorkspaceUpdateRequest\"];\ntype FileListResponse = components[\"schemas\"][\"FileListResponse\"];\ntype FileUploadRequest = components[\"schemas\"][\"FileUploadRequest\"];\ntype FileUploadResponse = components[\"schemas\"][\"FileUploadResponse\"];\n\nexport interface WorkspaceListParams {\n pageSize?: number;\n pageNumber?: number;\n}\n\nexport interface WorkspaceFilesParams {\n prefix?: string;\n limit?: number;\n cursor?: string | null;\n includeUrls?: boolean;\n shallow?: boolean;\n}\n\nexport class Workspaces {\n constructor(private readonly http: HttpClient) {}\n\n /** List workspaces for the authenticated project. */\n list(params?: WorkspaceListParams): Promise<WorkspaceListResponse> {\n return this.http.get<WorkspaceListResponse>(\"/workspaces\", params as Record<string, unknown>);\n }\n\n /** Create a new workspace. */\n create(body?: WorkspaceCreateRequest): Promise<WorkspaceView> {\n return this.http.post<WorkspaceView>(\"/workspaces\", body);\n }\n\n /** Get workspace details. */\n get(workspaceId: string): Promise<WorkspaceView> {\n return this.http.get<WorkspaceView>(`/workspaces/${workspaceId}`);\n }\n\n /** Update a workspace. */\n update(workspaceId: string, body: WorkspaceUpdateRequest): Promise<WorkspaceView> {\n return this.http.patch<WorkspaceView>(`/workspaces/${workspaceId}`, body);\n }\n\n /** Delete a workspace and its data. */\n delete(workspaceId: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}`);\n }\n\n /** List files in a workspace. */\n files(workspaceId: string, params?: WorkspaceFilesParams): Promise<FileListResponse> {\n return this.http.get<FileListResponse>(\n `/workspaces/${workspaceId}/files`,\n params as Record<string, unknown>,\n );\n }\n\n /** Get presigned upload URLs for workspace files. */\n uploadFiles(workspaceId: string, body: FileUploadRequest, query?: { prefix?: string }): Promise<FileUploadResponse> {\n return this.http.post<FileUploadResponse>(\n `/workspaces/${workspaceId}/files/upload`,\n body,\n query as Record<string, unknown>,\n );\n }\n\n /** Delete a file from a workspace. */\n deleteFile(workspaceId: string, path: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}/files`, { path });\n }\n\n /** Get storage usage for a workspace. */\n size(workspaceId: string): Promise<unknown> {\n return this.http.get<unknown>(`/workspaces/${workspaceId}/size`);\n }\n\n /**\n * Upload local files to a workspace. Returns the list of remote paths.\n *\n * ```ts\n * await client.workspaces.upload(wsId, \"data.csv\", \"config.json\");\n * await client.workspaces.upload(wsId, \"data.csv\", { prefix: \"uploads/\" });\n * ```\n */\n async upload(workspaceId: string, ...args: (string | { prefix?: string })[]): Promise<string[]> {\n let prefix: string | undefined;\n const paths: string[] = [];\n for (const arg of args) {\n if (typeof arg === \"string\") {\n paths.push(arg);\n } else if (typeof arg === \"object\" && arg !== null) {\n prefix = arg.prefix;\n }\n }\n if (paths.length === 0) {\n throw new Error(\"At least one file path is required\");\n }\n const items = paths.map((p) => ({\n name: basename(p),\n contentType: guessContentType(p),\n size: statSync(p).size,\n }));\n const resp = await this.uploadFiles(workspaceId, { files: items }, prefix ? { prefix } : undefined);\n for (let i = 0; i < paths.length; i++) {\n const body = readFileSync(paths[i]);\n const res = await fetch(resp.files[i].uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": items[i].contentType },\n body,\n });\n if (!res.ok) throw new Error(`Upload failed: ${res.status} ${res.statusText}`);\n }\n return resp.files.map((f) => f.path);\n }\n\n /**\n * Download a single file from a workspace. Returns the local path.\n *\n * ```ts\n * const local = await client.workspaces.download(wsId, \"uploads/data.csv\", { to: \"./data.csv\" });\n * ```\n */\n async download(workspaceId: string, path: string, options?: { to?: string }): Promise<string> {\n const fileList = await this.files(workspaceId, { prefix: path, includeUrls: true });\n const match = fileList.files?.find((f) => f.path === path);\n if (!match) throw new Error(`File not found in workspace: ${path}`);\n const dest = options?.to ?? basename(match.path);\n mkdirSync(dirname(dest), { recursive: true });\n const resp = await fetch(match.url!);\n if (!resp.ok) throw new Error(`Download failed: ${resp.status}`);\n writeFileSync(dest, Buffer.from(await resp.arrayBuffer()));\n return dest;\n }\n\n /**\n * Download all files from a workspace. Returns list of local paths.\n *\n * ```ts\n * const paths = await client.workspaces.downloadAll(wsId, { to: \"./output\" });\n * ```\n */\n async downloadAll(workspaceId: string, options?: { to?: string; prefix?: string }): Promise<string[]> {\n const destDir = options?.to ?? \".\";\n mkdirSync(destDir, { recursive: true });\n const results: string[] = [];\n let cursor: string | undefined;\n do {\n const fileList = await this.files(workspaceId, {\n prefix: options?.prefix,\n includeUrls: true,\n cursor,\n });\n for (const f of fileList.files ?? []) {\n const local = safeJoin(destDir, f.path);\n mkdirSync(dirname(local), { recursive: true });\n const resp = await fetch(f.url!);\n if (!resp.ok) throw new Error(`Download failed for ${f.path}: ${resp.status}`);\n writeFileSync(local, Buffer.from(await resp.arrayBuffer()));\n results.push(local);\n }\n cursor = fileList.hasMore ? (fileList.nextCursor ?? undefined) : undefined;\n } while (cursor);\n return results;\n }\n}\n","import type { z } from \"zod\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { Sessions } from \"./resources/sessions.js\";\n\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype MessageResponse = components[\"schemas\"][\"MessageResponse\"];\n\nconst TERMINAL_STATUSES = new Set([\"idle\", \"stopped\", \"timed_out\", \"error\"]);\n\nexport interface RunOptions {\n /** Maximum time to wait in milliseconds. Default: 14_400_000 (4 hours). */\n timeout?: number;\n /** Polling interval in milliseconds. Default: 2_000. */\n interval?: number;\n /** @internal Starting message cursor for follow-up runs on an existing session. */\n _startCursor?: string;\n}\n\n/** Session result with typed output. All SessionResponse fields are directly accessible. */\nexport type SessionResult<T = string | null> = Omit<SessionResponse, \"output\"> & { output: T };\n\n/**\n * Dual-purpose session handle: `await` it for a typed SessionResult,\n * or access `.result` for the full SessionResult after resolution.\n */\nexport class SessionRun<T = string> implements PromiseLike<SessionResult<T>> {\n private readonly _createPromise: Promise<SessionResponse>;\n private readonly _sessions: Sessions;\n private readonly _schema?: z.ZodType<T>;\n private readonly _timeout: number;\n private readonly _interval: number;\n private readonly _options?: RunOptions;\n private _sessionId: string | null = null;\n private _result: SessionResult<T> | null = null;\n\n constructor(\n createPromise: Promise<SessionResponse>,\n sessions: Sessions,\n schema?: z.ZodType<T>,\n options?: RunOptions,\n ) {\n this._createPromise = createPromise;\n this._sessions = sessions;\n this._schema = schema;\n this._timeout = options?.timeout ?? 14_400_000;\n this._interval = options?.interval ?? 2_000;\n this._options = options;\n }\n\n /** The session ID, available after task creation resolves. */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /** The full SessionResult, available after polling completes. */\n get result(): SessionResult<T> | null {\n return this._result;\n }\n\n /** Enable `await client.run(...)` — polls until terminal, returns SessionResult. */\n then<R1 = SessionResult<T>, R2 = never>(\n onFulfilled?:\n | ((value: SessionResult<T>) => R1 | PromiseLike<R1>)\n | null,\n onRejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null,\n ): Promise<R1 | R2> {\n return this._waitForOutput().then(onFulfilled, onRejected);\n }\n\n private async _ensureSessionId(): Promise<string> {\n if (this._sessionId) return this._sessionId;\n const created = await this._createPromise;\n this._sessionId = created.id;\n return this._sessionId;\n }\n\n /** Poll session until terminal, return SessionResult. */\n private async _waitForOutput(): Promise<SessionResult<T>> {\n const sessionId = await this._ensureSessionId();\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n const { output, ...rest } = session;\n const parsed = this._parseOutput(output);\n this._result = { ...rest, output: parsed } as SessionResult<T>;\n return this._result;\n }\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) =>\n setTimeout(r, Math.min(this._interval, remaining)),\n );\n }\n\n throw new Error(\n `Session ${sessionId} did not complete within ${this._timeout}ms`,\n );\n }\n\n /**\n * Enable `for await (const msg of client.run(...))` — yields messages as they appear.\n * After iteration, `.result` contains the final SessionResult.\n */\n async *[Symbol.asyncIterator](): AsyncGenerator<MessageResponse> {\n const sessionId = await this._ensureSessionId();\n let cursor: string | undefined = this._options?._startCursor;\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const resp = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n for (const msg of resp.messages) {\n yield msg;\n cursor = msg.id;\n }\n\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n // Drain all remaining messages (may be multiple pages)\n while (true) {\n const page = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n if (!page.messages.length) break;\n for (const msg of page.messages) {\n yield msg;\n cursor = msg.id;\n }\n }\n const { output, ...rest } = session;\n this._result = { ...rest, output: this._parseOutput(output) } as SessionResult<T>;\n return;\n }\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(this._interval, remaining)));\n }\n\n throw new Error(`Session ${sessionId} did not complete within ${this._timeout}ms`);\n }\n\n private _parseOutput(output: unknown): T {\n if (output == null) return null as T;\n if (!this._schema) return output as unknown as T;\n const raw = typeof output === \"string\" ? JSON.parse(output) : output;\n return this._schema.parse(raw);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/v3.cjs","../src/v3/client.ts","../src/v3/resources/billing.ts","../src/v3/resources/browsers.ts","../src/v3/resources/profiles.ts","../src/v3/resources/sessions.ts","../src/v3/resources/workspaces.ts","../src/v3/helpers.ts"],"names":[],"mappings":"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","file":"/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/v3.cjs","sourcesContent":[null,"import { z } from \"zod\";\nimport { HttpClient } from \"../core/http.js\";\nimport {\n X402_BASE_URL_DEFAULT,\n type X402Client,\n wrapFetchWithX402,\n x402ClientFromPrivateKey,\n} from \"../core/x402.js\";\nimport { Billing } from \"./resources/billing.js\";\nimport { Browsers } from \"./resources/browsers.js\";\nimport { Profiles } from \"./resources/profiles.js\";\nimport { Sessions } from \"./resources/sessions.js\";\nimport { Workspaces } from \"./resources/workspaces.js\";\nimport { SessionRun } from \"./helpers.js\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { RunOptions } from \"./helpers.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n\nconst DEFAULT_BASE_URL = \"https://api.browser-use.com/api/v3\";\n\nexport interface BrowserUseOptions {\n apiKey?: string;\n baseUrl?: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Use your own LLM API key configured in Browser Use project settings for v3 agent runs.\n */\n useOwnKey?: boolean;\n /**\n * Pre-built x402 client (advanced — for custom signers / multi-network).\n * If set, the SDK uses pay-per-request authentication via USDC instead of\n * an API key. Requires the optional peer deps `@x402/fetch`, `@x402/evm`,\n * and `viem`.\n */\n x402?: X402Client;\n /**\n * EVM wallet private key for x402 mode. Equivalent to building an x402\n * client from this key and passing it as `x402`. Falls back to\n * `BROWSER_USE_X402_PRIVATE_KEY`.\n */\n x402PrivateKey?: string;\n}\n\nexport type RunSessionOptions = Partial<Omit<RunTaskRequest, \"task\">> &\n RunOptions & { schema?: z.ZodType };\n\nexport class BrowserUse {\n readonly billing: Billing;\n readonly browsers: Browsers;\n readonly profiles: Profiles;\n readonly sessions: Sessions;\n readonly workspaces: Workspaces;\n\n private readonly http: HttpClient;\n\n constructor(options: BrowserUseOptions = {}) {\n const x402PrivateKey =\n options.x402PrivateKey ?? process.env.BROWSER_USE_X402_PRIVATE_KEY;\n\n if (options.x402 || x402PrivateKey) {\n // x402 mode — defer x402 client + wrapped fetch resolution to first request.\n // If apiKey is also set, it's forwarded as a header so the backend\n // credits the API key's project (top-up mode) instead of one keyed\n // to the wallet.\n const topupKey = options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n const fetchPromise = (async () => {\n const x402Client = options.x402 ?? (await x402ClientFromPrivateKey(x402PrivateKey!));\n return wrapFetchWithX402(globalThis.fetch, x402Client);\n })();\n // Suppress unhandled-rejection warnings if the user constructs the client\n // but never makes a request\n fetchPromise.catch(() => {});\n this.http = new HttpClient({\n apiKey: topupKey,\n baseUrl: options.baseUrl ?? X402_BASE_URL_DEFAULT,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n fetch: fetchPromise,\n });\n } else {\n const apiKey =\n options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"No credentials provided. Pass apiKey / set BROWSER_USE_API_KEY, \" +\n \"or pass x402PrivateKey / set BROWSER_USE_X402_PRIVATE_KEY for \" +\n \"pay-per-request access via USDC.\",\n );\n }\n this.http = new HttpClient({\n apiKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n });\n }\n\n this.billing = new Billing(this.http);\n this.browsers = new Browsers(this.http);\n this.profiles = new Profiles(this.http);\n this.sessions = new Sessions(this.http, { useOwnKey: options.useOwnKey });\n this.workspaces = new Workspaces(this.http);\n }\n\n /**\n * Create a session and run a task. `await` the result for a typed SessionResult.\n *\n * ```ts\n * // Simple — just get the output\n * const result = await client.run(\"Find the top HN post\");\n * console.log(result.output);\n *\n * // Structured output (Zod)\n * const result = await client.run(\"Find product info\", { schema: ProductSchema });\n * console.log(result.output.name); // fully typed\n * ```\n */\n run(task: string, options?: Omit<RunSessionOptions, \"schema\">): SessionRun<string>;\n run<T extends z.ZodType>(task: string, options: RunSessionOptions & { schema: T }): SessionRun<z.output<T>>;\n run(task: string, options?: RunSessionOptions): SessionRun<any> {\n const { schema, timeout, interval, ...rest } = options ?? {};\n const body = { task, ...rest } as RunTaskRequest;\n if (body.proxyCountryCode) {\n body.proxyCountryCode = body.proxyCountryCode.toLowerCase() as any;\n }\n if (schema) {\n if (typeof schema !== \"object\" || !(\"_zod\" in schema || \"_def\" in schema)) {\n throw new Error(\n \"schema must be a Zod schema (e.g. z.object({...})). \" +\n \"Make sure you are using Zod v4: npm install zod@4\"\n );\n }\n body.outputSchema = z.toJSONSchema(schema) as Record<string, unknown>;\n }\n // Auto keep_alive when dispatching to an existing session\n if (body.sessionId && body.keepAlive === undefined) {\n body.keepAlive = true;\n }\n // For follow-up runs on an existing session, snapshot the latest message\n // cursor before creating the new task so the iterator skips old messages.\n if (body.sessionId) {\n const sid = body.sessionId;\n const sessions = this.sessions;\n let startCursor: string | undefined;\n const promise = sessions\n .messages(sid, { limit: 1 })\n .then((resp) => {\n const last = resp.messages[resp.messages.length - 1];\n startCursor = last?.id;\n })\n .then(() => sessions.create(body));\n // startCursor is set before createPromise resolves, so the iterator\n // (which awaits _ensureSessionId first) will see the correct value.\n return new SessionRun(promise, this.sessions, schema, {\n timeout,\n interval,\n get _startCursor() { return startCursor; },\n });\n }\n const promise = this.sessions.create(body);\n return new SessionRun(promise, this.sessions, schema, { timeout, interval });\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype AccountView = components[\"schemas\"][\"AccountView\"];\n\nexport class Billing {\n constructor(private readonly http: HttpClient) {}\n\n /** Get account billing information. */\n account(): Promise<AccountView> {\n return this.http.get<AccountView>(\"/billing/account\");\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype CreateBrowserSessionRequest = components[\"schemas\"][\"CreateBrowserSessionRequest\"];\ntype BrowserSessionItemView = components[\"schemas\"][\"BrowserSessionItemView\"];\ntype BrowserSessionView = components[\"schemas\"][\"BrowserSessionView\"];\ntype BrowserSessionListResponse = components[\"schemas\"][\"BrowserSessionListResponse\"];\ntype UpdateBrowserSessionRequest = components[\"schemas\"][\"UpdateBrowserSessionRequest\"];\ntype BrowserDownloadListResponse = components[\"schemas\"][\"BrowserDownloadListResponse\"];\n\nexport interface BrowserListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface BrowserDownloadsParams {\n limit?: number;\n cursor?: string;\n includeUrls?: boolean;\n}\n\nexport class Browsers {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a standalone browser session. */\n create(body: Partial<CreateBrowserSessionRequest> = {}): Promise<BrowserSessionItemView> {\n return this.http.post<BrowserSessionItemView>(\"/browsers\", body);\n }\n\n /** List browser sessions for the authenticated project. */\n list(params?: BrowserListParams): Promise<BrowserSessionListResponse> {\n return this.http.get<BrowserSessionListResponse>(\"/browsers\", params as Record<string, unknown>);\n }\n\n /** Get browser session details. */\n get(sessionId: string): Promise<BrowserSessionView> {\n return this.http.get<BrowserSessionView>(`/browsers/${sessionId}`);\n }\n\n /** Update a browser session (e.g. stop it). */\n update(sessionId: string, body: UpdateBrowserSessionRequest): Promise<BrowserSessionView> {\n return this.http.patch<BrowserSessionView>(`/browsers/${sessionId}`, body);\n }\n\n /** Stop a browser session. Convenience wrapper around update. */\n stop(sessionId: string): Promise<BrowserSessionView> {\n return this.update(sessionId, { action: \"stop\" });\n }\n\n /** List files the browser downloaded to S3 during the session. */\n downloads(sessionId: string, params?: BrowserDownloadsParams): Promise<BrowserDownloadListResponse> {\n return this.http.get<BrowserDownloadListResponse>(\n `/browsers/${sessionId}/downloads`,\n params as Record<string, unknown>,\n );\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype ProfileView = components[\"schemas\"][\"ProfileView\"];\ntype ProfileListResponse = components[\"schemas\"][\"ProfileListResponse\"];\ntype ProfileCreateRequest = components[\"schemas\"][\"ProfileCreateRequest\"];\ntype ProfileUpdateRequest = components[\"schemas\"][\"ProfileUpdateRequest\"];\n\nexport interface ProfileListParams {\n query?: string;\n page?: number;\n page_size?: number;\n}\n\nexport class Profiles {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a browser profile. */\n create(body?: ProfileCreateRequest): Promise<ProfileView> {\n return this.http.post<ProfileView>(\"/profiles\", body);\n }\n\n /** List profiles for the authenticated project. */\n list(params?: ProfileListParams): Promise<ProfileListResponse> {\n return this.http.get<ProfileListResponse>(\"/profiles\", params as Record<string, unknown>);\n }\n\n /** Get profile details. */\n get(profileId: string): Promise<ProfileView> {\n return this.http.get<ProfileView>(`/profiles/${profileId}`);\n }\n\n /** Update a profile. */\n update(profileId: string, body: ProfileUpdateRequest): Promise<ProfileView> {\n return this.http.patch<ProfileView>(`/profiles/${profileId}`, body);\n }\n\n /** Delete a profile. */\n delete(profileId: string): Promise<void> {\n return this.http.delete<void>(`/profiles/${profileId}`);\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n/** All fields optional — omit `task` to create an idle session. */\nexport type CreateSessionBody = Partial<RunTaskRequest>;\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype SessionListResponse = components[\"schemas\"][\"SessionListResponse\"];\ntype StopSessionRequest = components[\"schemas\"][\"StopSessionRequest\"];\ntype MessageListResponse = components[\"schemas\"][\"MessageListResponse\"];\n\nexport interface SessionListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface SessionMessagesParams {\n after?: string | null;\n before?: string | null;\n limit?: number;\n}\n\nexport interface SessionsOptions {\n useOwnKey?: boolean;\n}\n\nexport class Sessions {\n constructor(\n private readonly http: HttpClient,\n private readonly options: SessionsOptions = {},\n ) {}\n\n /** Create a session and optionally dispatch a task. */\n create(body?: CreateSessionBody): Promise<SessionResponse> {\n const requestBody = { ...(body ?? {}) };\n if (\n this.options.useOwnKey !== undefined &&\n requestBody.useOwnKey === undefined\n ) {\n requestBody.useOwnKey = this.options.useOwnKey;\n }\n return this.http.post<SessionResponse>(\"/sessions\", requestBody);\n }\n\n /** List sessions for the authenticated project. */\n list(params?: SessionListParams): Promise<SessionListResponse> {\n return this.http.get<SessionListResponse>(\"/sessions\", params as Record<string, unknown>);\n }\n\n /** Get session details. */\n get(sessionId: string): Promise<SessionResponse> {\n return this.http.get<SessionResponse>(`/sessions/${sessionId}`);\n }\n\n /** Stop a session or the running task. */\n stop(sessionId: string, body?: StopSessionRequest): Promise<SessionResponse> {\n return this.http.post<SessionResponse>(`/sessions/${sessionId}/stop`, body);\n }\n\n /** Soft-delete a session. */\n delete(sessionId: string): Promise<void> {\n return this.http.delete<void>(`/sessions/${sessionId}`);\n }\n\n /** List messages for a session with cursor-based pagination. */\n messages(sessionId: string, params?: SessionMessagesParams): Promise<MessageListResponse> {\n return this.http.get<MessageListResponse>(\n `/sessions/${sessionId}/messages`,\n params as Record<string, unknown>,\n );\n }\n\n /**\n * Poll until recording URLs are available. Returns presigned MP4 URLs.\n *\n * Returns an empty array if no recording was produced (e.g. the agent\n * answered without opening a browser, or recording was not enabled).\n */\n async waitForRecording(\n sessionId: string,\n options?: { timeout?: number; interval?: number },\n ): Promise<string[]> {\n const timeout = options?.timeout ?? 15_000;\n const interval = options?.interval ?? 2_000;\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const session = await this.get(sessionId);\n if (session.recordingUrls?.length) return session.recordingUrls;\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(interval, remaining)));\n }\n return [];\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, statSync } from \"fs\";\nimport { basename, dirname, extname, join, resolve } from \"path\";\nimport type { HttpClient } from \"../../core/http.js\";\n\nfunction safeJoin(base: string, untrusted: string): string {\n const baseResolved = resolve(base) + \"/\";\n const resolved = resolve(base, untrusted);\n if (resolved !== resolve(base) && !resolved.startsWith(baseResolved)) {\n throw new Error(`Path traversal detected: ${untrusted}`);\n }\n return resolved;\n}\n\nconst MIME_TYPES: Record<string, string> = {\n \".csv\": \"text/csv\",\n \".json\": \"application/json\",\n \".txt\": \"text/plain\",\n \".md\": \"text/markdown\",\n \".html\": \"text/html\",\n \".xml\": \"application/xml\",\n \".yaml\": \"application/yaml\",\n \".yml\": \"application/yaml\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".zip\": \"application/zip\",\n \".gz\": \"application/gzip\",\n \".tar\": \"application/x-tar\",\n \".xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \".xls\": \"application/vnd.ms-excel\",\n \".docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".doc\": \"application/msword\",\n \".pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n};\n\nfunction guessContentType(path: string): string {\n return MIME_TYPES[extname(path).toLowerCase()] ?? \"application/octet-stream\";\n}\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype WorkspaceView = components[\"schemas\"][\"WorkspaceView\"];\ntype WorkspaceListResponse = components[\"schemas\"][\"WorkspaceListResponse\"];\ntype WorkspaceCreateRequest = components[\"schemas\"][\"WorkspaceCreateRequest\"];\ntype WorkspaceUpdateRequest = components[\"schemas\"][\"WorkspaceUpdateRequest\"];\ntype FileListResponse = components[\"schemas\"][\"FileListResponse\"];\ntype FileUploadRequest = components[\"schemas\"][\"FileUploadRequest\"];\ntype FileUploadResponse = components[\"schemas\"][\"FileUploadResponse\"];\n\nexport interface WorkspaceListParams {\n pageSize?: number;\n pageNumber?: number;\n}\n\nexport interface WorkspaceFilesParams {\n prefix?: string;\n limit?: number;\n cursor?: string | null;\n includeUrls?: boolean;\n shallow?: boolean;\n}\n\nexport class Workspaces {\n constructor(private readonly http: HttpClient) {}\n\n /** List workspaces for the authenticated project. */\n list(params?: WorkspaceListParams): Promise<WorkspaceListResponse> {\n return this.http.get<WorkspaceListResponse>(\"/workspaces\", params as Record<string, unknown>);\n }\n\n /** Create a new workspace. */\n create(body?: WorkspaceCreateRequest): Promise<WorkspaceView> {\n return this.http.post<WorkspaceView>(\"/workspaces\", body);\n }\n\n /** Get workspace details. */\n get(workspaceId: string): Promise<WorkspaceView> {\n return this.http.get<WorkspaceView>(`/workspaces/${workspaceId}`);\n }\n\n /** Update a workspace. */\n update(workspaceId: string, body: WorkspaceUpdateRequest): Promise<WorkspaceView> {\n return this.http.patch<WorkspaceView>(`/workspaces/${workspaceId}`, body);\n }\n\n /** Delete a workspace and its data. */\n delete(workspaceId: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}`);\n }\n\n /** List files in a workspace. */\n files(workspaceId: string, params?: WorkspaceFilesParams): Promise<FileListResponse> {\n return this.http.get<FileListResponse>(\n `/workspaces/${workspaceId}/files`,\n params as Record<string, unknown>,\n );\n }\n\n /** Get presigned upload URLs for workspace files. */\n uploadFiles(workspaceId: string, body: FileUploadRequest, query?: { prefix?: string }): Promise<FileUploadResponse> {\n return this.http.post<FileUploadResponse>(\n `/workspaces/${workspaceId}/files/upload`,\n body,\n query as Record<string, unknown>,\n );\n }\n\n /** Delete a file from a workspace. */\n deleteFile(workspaceId: string, path: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}/files`, { path });\n }\n\n /** Get storage usage for a workspace. */\n size(workspaceId: string): Promise<unknown> {\n return this.http.get<unknown>(`/workspaces/${workspaceId}/size`);\n }\n\n /**\n * Upload local files to a workspace. Returns the list of remote paths.\n *\n * ```ts\n * await client.workspaces.upload(wsId, \"data.csv\", \"config.json\");\n * await client.workspaces.upload(wsId, \"data.csv\", { prefix: \"uploads/\" });\n * ```\n */\n async upload(workspaceId: string, ...args: (string | { prefix?: string })[]): Promise<string[]> {\n let prefix: string | undefined;\n const paths: string[] = [];\n for (const arg of args) {\n if (typeof arg === \"string\") {\n paths.push(arg);\n } else if (typeof arg === \"object\" && arg !== null) {\n prefix = arg.prefix;\n }\n }\n if (paths.length === 0) {\n throw new Error(\"At least one file path is required\");\n }\n const items = paths.map((p) => ({\n name: basename(p),\n contentType: guessContentType(p),\n size: statSync(p).size,\n }));\n const resp = await this.uploadFiles(workspaceId, { files: items }, prefix ? { prefix } : undefined);\n for (let i = 0; i < paths.length; i++) {\n const body = readFileSync(paths[i]);\n const res = await fetch(resp.files[i].uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": items[i].contentType },\n body,\n });\n if (!res.ok) throw new Error(`Upload failed: ${res.status} ${res.statusText}`);\n }\n return resp.files.map((f) => f.path);\n }\n\n /**\n * Download a single file from a workspace. Returns the local path.\n *\n * ```ts\n * const local = await client.workspaces.download(wsId, \"uploads/data.csv\", { to: \"./data.csv\" });\n * ```\n */\n async download(workspaceId: string, path: string, options?: { to?: string }): Promise<string> {\n const fileList = await this.files(workspaceId, { prefix: path, includeUrls: true });\n const match = fileList.files?.find((f) => f.path === path);\n if (!match) throw new Error(`File not found in workspace: ${path}`);\n const dest = options?.to ?? basename(match.path);\n mkdirSync(dirname(dest), { recursive: true });\n const resp = await fetch(match.url!);\n if (!resp.ok) throw new Error(`Download failed: ${resp.status}`);\n writeFileSync(dest, Buffer.from(await resp.arrayBuffer()));\n return dest;\n }\n\n /**\n * Download all files from a workspace. Returns list of local paths.\n *\n * ```ts\n * const paths = await client.workspaces.downloadAll(wsId, { to: \"./output\" });\n * ```\n */\n async downloadAll(workspaceId: string, options?: { to?: string; prefix?: string }): Promise<string[]> {\n const destDir = options?.to ?? \".\";\n mkdirSync(destDir, { recursive: true });\n const results: string[] = [];\n let cursor: string | undefined;\n do {\n const fileList = await this.files(workspaceId, {\n prefix: options?.prefix,\n includeUrls: true,\n cursor,\n });\n for (const f of fileList.files ?? []) {\n const local = safeJoin(destDir, f.path);\n mkdirSync(dirname(local), { recursive: true });\n const resp = await fetch(f.url!);\n if (!resp.ok) throw new Error(`Download failed for ${f.path}: ${resp.status}`);\n writeFileSync(local, Buffer.from(await resp.arrayBuffer()));\n results.push(local);\n }\n cursor = fileList.hasMore ? (fileList.nextCursor ?? undefined) : undefined;\n } while (cursor);\n return results;\n }\n}\n","import type { z } from \"zod\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { Sessions } from \"./resources/sessions.js\";\n\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype MessageResponse = components[\"schemas\"][\"MessageResponse\"];\n\nconst TERMINAL_STATUSES = new Set([\"idle\", \"stopped\", \"timed_out\", \"error\"]);\n\nexport interface RunOptions {\n /** Maximum time to wait in milliseconds. Default: 14_400_000 (4 hours). */\n timeout?: number;\n /** Polling interval in milliseconds. Default: 2_000. */\n interval?: number;\n /** @internal Starting message cursor for follow-up runs on an existing session. */\n _startCursor?: string;\n}\n\n/** Session result with typed output. All SessionResponse fields are directly accessible. */\nexport type SessionResult<T = string | null> = Omit<SessionResponse, \"output\"> & { output: T };\n\n/**\n * Dual-purpose session handle: `await` it for a typed SessionResult,\n * or access `.result` for the full SessionResult after resolution.\n */\nexport class SessionRun<T = string> implements PromiseLike<SessionResult<T>> {\n private readonly _createPromise: Promise<SessionResponse>;\n private readonly _sessions: Sessions;\n private readonly _schema?: z.ZodType<T>;\n private readonly _timeout: number;\n private readonly _interval: number;\n private readonly _options?: RunOptions;\n private _sessionId: string | null = null;\n private _result: SessionResult<T> | null = null;\n\n constructor(\n createPromise: Promise<SessionResponse>,\n sessions: Sessions,\n schema?: z.ZodType<T>,\n options?: RunOptions,\n ) {\n this._createPromise = createPromise;\n this._sessions = sessions;\n this._schema = schema;\n this._timeout = options?.timeout ?? 14_400_000;\n this._interval = options?.interval ?? 2_000;\n this._options = options;\n }\n\n /** The session ID, available after task creation resolves. */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /** The full SessionResult, available after polling completes. */\n get result(): SessionResult<T> | null {\n return this._result;\n }\n\n /** Enable `await client.run(...)` — polls until terminal, returns SessionResult. */\n then<R1 = SessionResult<T>, R2 = never>(\n onFulfilled?:\n | ((value: SessionResult<T>) => R1 | PromiseLike<R1>)\n | null,\n onRejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null,\n ): Promise<R1 | R2> {\n return this._waitForOutput().then(onFulfilled, onRejected);\n }\n\n private async _ensureSessionId(): Promise<string> {\n if (this._sessionId) return this._sessionId;\n const created = await this._createPromise;\n this._sessionId = created.id;\n return this._sessionId;\n }\n\n /** Poll session until terminal, return SessionResult. */\n private async _waitForOutput(): Promise<SessionResult<T>> {\n const sessionId = await this._ensureSessionId();\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n const { output, ...rest } = session;\n const parsed = this._parseOutput(output);\n this._result = { ...rest, output: parsed } as SessionResult<T>;\n return this._result;\n }\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) =>\n setTimeout(r, Math.min(this._interval, remaining)),\n );\n }\n\n throw new Error(\n `Session ${sessionId} did not complete within ${this._timeout}ms`,\n );\n }\n\n /**\n * Enable `for await (const msg of client.run(...))` — yields messages as they appear.\n * After iteration, `.result` contains the final SessionResult.\n */\n async *[Symbol.asyncIterator](): AsyncGenerator<MessageResponse> {\n const sessionId = await this._ensureSessionId();\n let cursor: string | undefined = this._options?._startCursor;\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const resp = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n for (const msg of resp.messages) {\n yield msg;\n cursor = msg.id;\n }\n\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n // Drain all remaining messages (may be multiple pages)\n while (true) {\n const page = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n if (!page.messages.length) break;\n for (const msg of page.messages) {\n yield msg;\n cursor = msg.id;\n }\n }\n const { output, ...rest } = session;\n this._result = { ...rest, output: this._parseOutput(output) } as SessionResult<T>;\n return;\n }\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(this._interval, remaining)));\n }\n\n throw new Error(`Session ${sessionId} did not complete within ${this._timeout}ms`);\n }\n\n private _parseOutput(output: unknown): T {\n if (output == null) return null as T;\n if (!this._schema) return output as unknown as T;\n const raw = typeof output === \"string\" ? JSON.parse(output) : output;\n return this._schema.parse(raw);\n }\n}\n"]}
|
package/dist/v3.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { H as HttpClient, X as X402Client } from './errors-
|
|
3
|
-
export { B as BrowserUseError } from './errors-
|
|
2
|
+
import { H as HttpClient, X as X402Client } from './errors-DaHgFhIQ.cjs';
|
|
3
|
+
export { B as BrowserUseError, a as X402WalletBalance, g as getWalletBalance } from './errors-DaHgFhIQ.cjs';
|
|
4
4
|
|
|
5
5
|
interface components {
|
|
6
6
|
schemas: {
|
|
@@ -494,7 +494,7 @@ interface components {
|
|
|
494
494
|
proxyCountryCode: components["schemas"]["ProxyCountryCode"] | null;
|
|
495
495
|
/**
|
|
496
496
|
* Timeout
|
|
497
|
-
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours).
|
|
497
|
+
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours). Browser sessions are charged $0.02/hour.
|
|
498
498
|
* @default 60
|
|
499
499
|
*/
|
|
500
500
|
timeout: number;
|
package/dist/v3.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { H as HttpClient, X as X402Client } from './errors-
|
|
3
|
-
export { B as BrowserUseError } from './errors-
|
|
2
|
+
import { H as HttpClient, X as X402Client } from './errors-DaHgFhIQ.js';
|
|
3
|
+
export { B as BrowserUseError, a as X402WalletBalance, g as getWalletBalance } from './errors-DaHgFhIQ.js';
|
|
4
4
|
|
|
5
5
|
interface components {
|
|
6
6
|
schemas: {
|
|
@@ -494,7 +494,7 @@ interface components {
|
|
|
494
494
|
proxyCountryCode: components["schemas"]["ProxyCountryCode"] | null;
|
|
495
495
|
/**
|
|
496
496
|
* Timeout
|
|
497
|
-
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours).
|
|
497
|
+
* @description The timeout for the session in minutes. All users can use up to 240 minutes (4 hours). Browser sessions are charged $0.02/hour.
|
|
498
498
|
* @default 60
|
|
499
499
|
*/
|
|
500
500
|
timeout: number;
|
package/dist/v3.js
CHANGED
|
@@ -2,9 +2,10 @@ import {
|
|
|
2
2
|
BrowserUseError,
|
|
3
3
|
HttpClient,
|
|
4
4
|
X402_BASE_URL_DEFAULT,
|
|
5
|
+
getWalletBalance,
|
|
5
6
|
wrapFetchWithX402,
|
|
6
7
|
x402ClientFromPrivateKey
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ESJIWN3M.js";
|
|
8
9
|
|
|
9
10
|
// src/v3/client.ts
|
|
10
11
|
import { z } from "zod";
|
|
@@ -508,6 +509,7 @@ export {
|
|
|
508
509
|
Profiles,
|
|
509
510
|
SessionRun,
|
|
510
511
|
Sessions,
|
|
511
|
-
Workspaces
|
|
512
|
+
Workspaces,
|
|
513
|
+
getWalletBalance
|
|
512
514
|
};
|
|
513
515
|
//# sourceMappingURL=v3.js.map
|
package/dist/v3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/v3/client.ts","../src/v3/resources/billing.ts","../src/v3/resources/browsers.ts","../src/v3/resources/profiles.ts","../src/v3/resources/sessions.ts","../src/v3/resources/workspaces.ts","../src/v3/helpers.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { HttpClient } from \"../core/http.js\";\nimport {\n X402_BASE_URL_DEFAULT,\n type X402Client,\n wrapFetchWithX402,\n x402ClientFromPrivateKey,\n} from \"../core/x402.js\";\nimport { Billing } from \"./resources/billing.js\";\nimport { Browsers } from \"./resources/browsers.js\";\nimport { Profiles } from \"./resources/profiles.js\";\nimport { Sessions } from \"./resources/sessions.js\";\nimport { Workspaces } from \"./resources/workspaces.js\";\nimport { SessionRun } from \"./helpers.js\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { RunOptions } from \"./helpers.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n\nconst DEFAULT_BASE_URL = \"https://api.browser-use.com/api/v3\";\n\nexport interface BrowserUseOptions {\n apiKey?: string;\n baseUrl?: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Use your own LLM API key configured in Browser Use project settings for v3 agent runs.\n */\n useOwnKey?: boolean;\n /**\n * Pre-built x402 client (advanced — for custom signers / multi-network).\n * If set, the SDK uses pay-per-request authentication via USDC instead of\n * an API key. Requires the optional peer deps `@x402/fetch`, `@x402/evm`,\n * and `viem`.\n */\n x402?: X402Client;\n /**\n * EVM wallet private key for x402 mode. Equivalent to building an x402\n * client from this key and passing it as `x402`. Falls back to\n * `BROWSER_USE_X402_PRIVATE_KEY`.\n */\n x402PrivateKey?: string;\n}\n\nexport type RunSessionOptions = Partial<Omit<RunTaskRequest, \"task\">> &\n RunOptions & { schema?: z.ZodType };\n\nexport class BrowserUse {\n readonly billing: Billing;\n readonly browsers: Browsers;\n readonly profiles: Profiles;\n readonly sessions: Sessions;\n readonly workspaces: Workspaces;\n\n private readonly http: HttpClient;\n\n constructor(options: BrowserUseOptions = {}) {\n const x402PrivateKey =\n options.x402PrivateKey ?? process.env.BROWSER_USE_X402_PRIVATE_KEY;\n\n if (options.x402 || x402PrivateKey) {\n // x402 mode — defer x402 client + wrapped fetch resolution to first request.\n // If apiKey is also set, it's forwarded as a header so the backend\n // credits the API key's project (top-up mode) instead of one keyed\n // to the wallet.\n const topupKey = options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n const fetchPromise = (async () => {\n const x402Client = options.x402 ?? (await x402ClientFromPrivateKey(x402PrivateKey!));\n return wrapFetchWithX402(globalThis.fetch, x402Client);\n })();\n // Suppress unhandled-rejection warnings if the user constructs the client\n // but never makes a request\n fetchPromise.catch(() => {});\n this.http = new HttpClient({\n apiKey: topupKey,\n baseUrl: options.baseUrl ?? X402_BASE_URL_DEFAULT,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n fetch: fetchPromise,\n });\n } else {\n const apiKey =\n options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"No credentials provided. Pass apiKey / set BROWSER_USE_API_KEY, \" +\n \"or pass x402PrivateKey / set BROWSER_USE_X402_PRIVATE_KEY for \" +\n \"pay-per-request access via USDC.\",\n );\n }\n this.http = new HttpClient({\n apiKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n });\n }\n\n this.billing = new Billing(this.http);\n this.browsers = new Browsers(this.http);\n this.profiles = new Profiles(this.http);\n this.sessions = new Sessions(this.http, { useOwnKey: options.useOwnKey });\n this.workspaces = new Workspaces(this.http);\n }\n\n /**\n * Create a session and run a task. `await` the result for a typed SessionResult.\n *\n * ```ts\n * // Simple — just get the output\n * const result = await client.run(\"Find the top HN post\");\n * console.log(result.output);\n *\n * // Structured output (Zod)\n * const result = await client.run(\"Find product info\", { schema: ProductSchema });\n * console.log(result.output.name); // fully typed\n * ```\n */\n run(task: string, options?: Omit<RunSessionOptions, \"schema\">): SessionRun<string>;\n run<T extends z.ZodType>(task: string, options: RunSessionOptions & { schema: T }): SessionRun<z.output<T>>;\n run(task: string, options?: RunSessionOptions): SessionRun<any> {\n const { schema, timeout, interval, ...rest } = options ?? {};\n const body = { task, ...rest } as RunTaskRequest;\n if (body.proxyCountryCode) {\n body.proxyCountryCode = body.proxyCountryCode.toLowerCase() as any;\n }\n if (schema) {\n if (typeof schema !== \"object\" || !(\"_zod\" in schema || \"_def\" in schema)) {\n throw new Error(\n \"schema must be a Zod schema (e.g. z.object({...})). \" +\n \"Make sure you are using Zod v4: npm install zod@4\"\n );\n }\n body.outputSchema = z.toJSONSchema(schema) as Record<string, unknown>;\n }\n // Auto keep_alive when dispatching to an existing session\n if (body.sessionId && body.keepAlive === undefined) {\n body.keepAlive = true;\n }\n // For follow-up runs on an existing session, snapshot the latest message\n // cursor before creating the new task so the iterator skips old messages.\n if (body.sessionId) {\n const sid = body.sessionId;\n const sessions = this.sessions;\n let startCursor: string | undefined;\n const promise = sessions\n .messages(sid, { limit: 1 })\n .then((resp) => {\n const last = resp.messages[resp.messages.length - 1];\n startCursor = last?.id;\n })\n .then(() => sessions.create(body));\n // startCursor is set before createPromise resolves, so the iterator\n // (which awaits _ensureSessionId first) will see the correct value.\n return new SessionRun(promise, this.sessions, schema, {\n timeout,\n interval,\n get _startCursor() { return startCursor; },\n });\n }\n const promise = this.sessions.create(body);\n return new SessionRun(promise, this.sessions, schema, { timeout, interval });\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype AccountView = components[\"schemas\"][\"AccountView\"];\n\nexport class Billing {\n constructor(private readonly http: HttpClient) {}\n\n /** Get account billing information. */\n account(): Promise<AccountView> {\n return this.http.get<AccountView>(\"/billing/account\");\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype CreateBrowserSessionRequest = components[\"schemas\"][\"CreateBrowserSessionRequest\"];\ntype BrowserSessionItemView = components[\"schemas\"][\"BrowserSessionItemView\"];\ntype BrowserSessionView = components[\"schemas\"][\"BrowserSessionView\"];\ntype BrowserSessionListResponse = components[\"schemas\"][\"BrowserSessionListResponse\"];\ntype UpdateBrowserSessionRequest = components[\"schemas\"][\"UpdateBrowserSessionRequest\"];\ntype BrowserDownloadListResponse = components[\"schemas\"][\"BrowserDownloadListResponse\"];\n\nexport interface BrowserListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface BrowserDownloadsParams {\n limit?: number;\n cursor?: string;\n includeUrls?: boolean;\n}\n\nexport class Browsers {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a standalone browser session. */\n create(body: Partial<CreateBrowserSessionRequest> = {}): Promise<BrowserSessionItemView> {\n return this.http.post<BrowserSessionItemView>(\"/browsers\", body);\n }\n\n /** List browser sessions for the authenticated project. */\n list(params?: BrowserListParams): Promise<BrowserSessionListResponse> {\n return this.http.get<BrowserSessionListResponse>(\"/browsers\", params as Record<string, unknown>);\n }\n\n /** Get browser session details. */\n get(sessionId: string): Promise<BrowserSessionView> {\n return this.http.get<BrowserSessionView>(`/browsers/${sessionId}`);\n }\n\n /** Update a browser session (e.g. stop it). */\n update(sessionId: string, body: UpdateBrowserSessionRequest): Promise<BrowserSessionView> {\n return this.http.patch<BrowserSessionView>(`/browsers/${sessionId}`, body);\n }\n\n /** Stop a browser session. Convenience wrapper around update. */\n stop(sessionId: string): Promise<BrowserSessionView> {\n return this.update(sessionId, { action: \"stop\" });\n }\n\n /** List files the browser downloaded to S3 during the session. */\n downloads(sessionId: string, params?: BrowserDownloadsParams): Promise<BrowserDownloadListResponse> {\n return this.http.get<BrowserDownloadListResponse>(\n `/browsers/${sessionId}/downloads`,\n params as Record<string, unknown>,\n );\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype ProfileView = components[\"schemas\"][\"ProfileView\"];\ntype ProfileListResponse = components[\"schemas\"][\"ProfileListResponse\"];\ntype ProfileCreateRequest = components[\"schemas\"][\"ProfileCreateRequest\"];\ntype ProfileUpdateRequest = components[\"schemas\"][\"ProfileUpdateRequest\"];\n\nexport interface ProfileListParams {\n query?: string;\n page?: number;\n page_size?: number;\n}\n\nexport class Profiles {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a browser profile. */\n create(body?: ProfileCreateRequest): Promise<ProfileView> {\n return this.http.post<ProfileView>(\"/profiles\", body);\n }\n\n /** List profiles for the authenticated project. */\n list(params?: ProfileListParams): Promise<ProfileListResponse> {\n return this.http.get<ProfileListResponse>(\"/profiles\", params as Record<string, unknown>);\n }\n\n /** Get profile details. */\n get(profileId: string): Promise<ProfileView> {\n return this.http.get<ProfileView>(`/profiles/${profileId}`);\n }\n\n /** Update a profile. */\n update(profileId: string, body: ProfileUpdateRequest): Promise<ProfileView> {\n return this.http.patch<ProfileView>(`/profiles/${profileId}`, body);\n }\n\n /** Delete a profile. */\n delete(profileId: string): Promise<void> {\n return this.http.delete<void>(`/profiles/${profileId}`);\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n/** All fields optional — omit `task` to create an idle session. */\nexport type CreateSessionBody = Partial<RunTaskRequest>;\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype SessionListResponse = components[\"schemas\"][\"SessionListResponse\"];\ntype StopSessionRequest = components[\"schemas\"][\"StopSessionRequest\"];\ntype MessageListResponse = components[\"schemas\"][\"MessageListResponse\"];\n\nexport interface SessionListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface SessionMessagesParams {\n after?: string | null;\n before?: string | null;\n limit?: number;\n}\n\nexport interface SessionsOptions {\n useOwnKey?: boolean;\n}\n\nexport class Sessions {\n constructor(\n private readonly http: HttpClient,\n private readonly options: SessionsOptions = {},\n ) {}\n\n /** Create a session and optionally dispatch a task. */\n create(body?: CreateSessionBody): Promise<SessionResponse> {\n const requestBody = { ...(body ?? {}) };\n if (\n this.options.useOwnKey !== undefined &&\n requestBody.useOwnKey === undefined\n ) {\n requestBody.useOwnKey = this.options.useOwnKey;\n }\n return this.http.post<SessionResponse>(\"/sessions\", requestBody);\n }\n\n /** List sessions for the authenticated project. */\n list(params?: SessionListParams): Promise<SessionListResponse> {\n return this.http.get<SessionListResponse>(\"/sessions\", params as Record<string, unknown>);\n }\n\n /** Get session details. */\n get(sessionId: string): Promise<SessionResponse> {\n return this.http.get<SessionResponse>(`/sessions/${sessionId}`);\n }\n\n /** Stop a session or the running task. */\n stop(sessionId: string, body?: StopSessionRequest): Promise<SessionResponse> {\n return this.http.post<SessionResponse>(`/sessions/${sessionId}/stop`, body);\n }\n\n /** Soft-delete a session. */\n delete(sessionId: string): Promise<void> {\n return this.http.delete<void>(`/sessions/${sessionId}`);\n }\n\n /** List messages for a session with cursor-based pagination. */\n messages(sessionId: string, params?: SessionMessagesParams): Promise<MessageListResponse> {\n return this.http.get<MessageListResponse>(\n `/sessions/${sessionId}/messages`,\n params as Record<string, unknown>,\n );\n }\n\n /**\n * Poll until recording URLs are available. Returns presigned MP4 URLs.\n *\n * Returns an empty array if no recording was produced (e.g. the agent\n * answered without opening a browser, or recording was not enabled).\n */\n async waitForRecording(\n sessionId: string,\n options?: { timeout?: number; interval?: number },\n ): Promise<string[]> {\n const timeout = options?.timeout ?? 15_000;\n const interval = options?.interval ?? 2_000;\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const session = await this.get(sessionId);\n if (session.recordingUrls?.length) return session.recordingUrls;\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(interval, remaining)));\n }\n return [];\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, statSync } from \"fs\";\nimport { basename, dirname, extname, join, resolve } from \"path\";\nimport type { HttpClient } from \"../../core/http.js\";\n\nfunction safeJoin(base: string, untrusted: string): string {\n const baseResolved = resolve(base) + \"/\";\n const resolved = resolve(base, untrusted);\n if (resolved !== resolve(base) && !resolved.startsWith(baseResolved)) {\n throw new Error(`Path traversal detected: ${untrusted}`);\n }\n return resolved;\n}\n\nconst MIME_TYPES: Record<string, string> = {\n \".csv\": \"text/csv\",\n \".json\": \"application/json\",\n \".txt\": \"text/plain\",\n \".md\": \"text/markdown\",\n \".html\": \"text/html\",\n \".xml\": \"application/xml\",\n \".yaml\": \"application/yaml\",\n \".yml\": \"application/yaml\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".zip\": \"application/zip\",\n \".gz\": \"application/gzip\",\n \".tar\": \"application/x-tar\",\n \".xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \".xls\": \"application/vnd.ms-excel\",\n \".docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".doc\": \"application/msword\",\n \".pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n};\n\nfunction guessContentType(path: string): string {\n return MIME_TYPES[extname(path).toLowerCase()] ?? \"application/octet-stream\";\n}\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype WorkspaceView = components[\"schemas\"][\"WorkspaceView\"];\ntype WorkspaceListResponse = components[\"schemas\"][\"WorkspaceListResponse\"];\ntype WorkspaceCreateRequest = components[\"schemas\"][\"WorkspaceCreateRequest\"];\ntype WorkspaceUpdateRequest = components[\"schemas\"][\"WorkspaceUpdateRequest\"];\ntype FileListResponse = components[\"schemas\"][\"FileListResponse\"];\ntype FileUploadRequest = components[\"schemas\"][\"FileUploadRequest\"];\ntype FileUploadResponse = components[\"schemas\"][\"FileUploadResponse\"];\n\nexport interface WorkspaceListParams {\n pageSize?: number;\n pageNumber?: number;\n}\n\nexport interface WorkspaceFilesParams {\n prefix?: string;\n limit?: number;\n cursor?: string | null;\n includeUrls?: boolean;\n shallow?: boolean;\n}\n\nexport class Workspaces {\n constructor(private readonly http: HttpClient) {}\n\n /** List workspaces for the authenticated project. */\n list(params?: WorkspaceListParams): Promise<WorkspaceListResponse> {\n return this.http.get<WorkspaceListResponse>(\"/workspaces\", params as Record<string, unknown>);\n }\n\n /** Create a new workspace. */\n create(body?: WorkspaceCreateRequest): Promise<WorkspaceView> {\n return this.http.post<WorkspaceView>(\"/workspaces\", body);\n }\n\n /** Get workspace details. */\n get(workspaceId: string): Promise<WorkspaceView> {\n return this.http.get<WorkspaceView>(`/workspaces/${workspaceId}`);\n }\n\n /** Update a workspace. */\n update(workspaceId: string, body: WorkspaceUpdateRequest): Promise<WorkspaceView> {\n return this.http.patch<WorkspaceView>(`/workspaces/${workspaceId}`, body);\n }\n\n /** Delete a workspace and its data. */\n delete(workspaceId: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}`);\n }\n\n /** List files in a workspace. */\n files(workspaceId: string, params?: WorkspaceFilesParams): Promise<FileListResponse> {\n return this.http.get<FileListResponse>(\n `/workspaces/${workspaceId}/files`,\n params as Record<string, unknown>,\n );\n }\n\n /** Get presigned upload URLs for workspace files. */\n uploadFiles(workspaceId: string, body: FileUploadRequest, query?: { prefix?: string }): Promise<FileUploadResponse> {\n return this.http.post<FileUploadResponse>(\n `/workspaces/${workspaceId}/files/upload`,\n body,\n query as Record<string, unknown>,\n );\n }\n\n /** Delete a file from a workspace. */\n deleteFile(workspaceId: string, path: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}/files`, { path });\n }\n\n /** Get storage usage for a workspace. */\n size(workspaceId: string): Promise<unknown> {\n return this.http.get<unknown>(`/workspaces/${workspaceId}/size`);\n }\n\n /**\n * Upload local files to a workspace. Returns the list of remote paths.\n *\n * ```ts\n * await client.workspaces.upload(wsId, \"data.csv\", \"config.json\");\n * await client.workspaces.upload(wsId, \"data.csv\", { prefix: \"uploads/\" });\n * ```\n */\n async upload(workspaceId: string, ...args: (string | { prefix?: string })[]): Promise<string[]> {\n let prefix: string | undefined;\n const paths: string[] = [];\n for (const arg of args) {\n if (typeof arg === \"string\") {\n paths.push(arg);\n } else if (typeof arg === \"object\" && arg !== null) {\n prefix = arg.prefix;\n }\n }\n if (paths.length === 0) {\n throw new Error(\"At least one file path is required\");\n }\n const items = paths.map((p) => ({\n name: basename(p),\n contentType: guessContentType(p),\n size: statSync(p).size,\n }));\n const resp = await this.uploadFiles(workspaceId, { files: items }, prefix ? { prefix } : undefined);\n for (let i = 0; i < paths.length; i++) {\n const body = readFileSync(paths[i]);\n const res = await fetch(resp.files[i].uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": items[i].contentType },\n body,\n });\n if (!res.ok) throw new Error(`Upload failed: ${res.status} ${res.statusText}`);\n }\n return resp.files.map((f) => f.path);\n }\n\n /**\n * Download a single file from a workspace. Returns the local path.\n *\n * ```ts\n * const local = await client.workspaces.download(wsId, \"uploads/data.csv\", { to: \"./data.csv\" });\n * ```\n */\n async download(workspaceId: string, path: string, options?: { to?: string }): Promise<string> {\n const fileList = await this.files(workspaceId, { prefix: path, includeUrls: true });\n const match = fileList.files?.find((f) => f.path === path);\n if (!match) throw new Error(`File not found in workspace: ${path}`);\n const dest = options?.to ?? basename(match.path);\n mkdirSync(dirname(dest), { recursive: true });\n const resp = await fetch(match.url!);\n if (!resp.ok) throw new Error(`Download failed: ${resp.status}`);\n writeFileSync(dest, Buffer.from(await resp.arrayBuffer()));\n return dest;\n }\n\n /**\n * Download all files from a workspace. Returns list of local paths.\n *\n * ```ts\n * const paths = await client.workspaces.downloadAll(wsId, { to: \"./output\" });\n * ```\n */\n async downloadAll(workspaceId: string, options?: { to?: string; prefix?: string }): Promise<string[]> {\n const destDir = options?.to ?? \".\";\n mkdirSync(destDir, { recursive: true });\n const results: string[] = [];\n let cursor: string | undefined;\n do {\n const fileList = await this.files(workspaceId, {\n prefix: options?.prefix,\n includeUrls: true,\n cursor,\n });\n for (const f of fileList.files ?? []) {\n const local = safeJoin(destDir, f.path);\n mkdirSync(dirname(local), { recursive: true });\n const resp = await fetch(f.url!);\n if (!resp.ok) throw new Error(`Download failed for ${f.path}: ${resp.status}`);\n writeFileSync(local, Buffer.from(await resp.arrayBuffer()));\n results.push(local);\n }\n cursor = fileList.hasMore ? (fileList.nextCursor ?? undefined) : undefined;\n } while (cursor);\n return results;\n }\n}\n","import type { z } from \"zod\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { Sessions } from \"./resources/sessions.js\";\n\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype MessageResponse = components[\"schemas\"][\"MessageResponse\"];\n\nconst TERMINAL_STATUSES = new Set([\"idle\", \"stopped\", \"timed_out\", \"error\"]);\n\nexport interface RunOptions {\n /** Maximum time to wait in milliseconds. Default: 14_400_000 (4 hours). */\n timeout?: number;\n /** Polling interval in milliseconds. Default: 2_000. */\n interval?: number;\n /** @internal Starting message cursor for follow-up runs on an existing session. */\n _startCursor?: string;\n}\n\n/** Session result with typed output. All SessionResponse fields are directly accessible. */\nexport type SessionResult<T = string | null> = Omit<SessionResponse, \"output\"> & { output: T };\n\n/**\n * Dual-purpose session handle: `await` it for a typed SessionResult,\n * or access `.result` for the full SessionResult after resolution.\n */\nexport class SessionRun<T = string> implements PromiseLike<SessionResult<T>> {\n private readonly _createPromise: Promise<SessionResponse>;\n private readonly _sessions: Sessions;\n private readonly _schema?: z.ZodType<T>;\n private readonly _timeout: number;\n private readonly _interval: number;\n private readonly _options?: RunOptions;\n private _sessionId: string | null = null;\n private _result: SessionResult<T> | null = null;\n\n constructor(\n createPromise: Promise<SessionResponse>,\n sessions: Sessions,\n schema?: z.ZodType<T>,\n options?: RunOptions,\n ) {\n this._createPromise = createPromise;\n this._sessions = sessions;\n this._schema = schema;\n this._timeout = options?.timeout ?? 14_400_000;\n this._interval = options?.interval ?? 2_000;\n this._options = options;\n }\n\n /** The session ID, available after task creation resolves. */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /** The full SessionResult, available after polling completes. */\n get result(): SessionResult<T> | null {\n return this._result;\n }\n\n /** Enable `await client.run(...)` — polls until terminal, returns SessionResult. */\n then<R1 = SessionResult<T>, R2 = never>(\n onFulfilled?:\n | ((value: SessionResult<T>) => R1 | PromiseLike<R1>)\n | null,\n onRejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null,\n ): Promise<R1 | R2> {\n return this._waitForOutput().then(onFulfilled, onRejected);\n }\n\n private async _ensureSessionId(): Promise<string> {\n if (this._sessionId) return this._sessionId;\n const created = await this._createPromise;\n this._sessionId = created.id;\n return this._sessionId;\n }\n\n /** Poll session until terminal, return SessionResult. */\n private async _waitForOutput(): Promise<SessionResult<T>> {\n const sessionId = await this._ensureSessionId();\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n const { output, ...rest } = session;\n const parsed = this._parseOutput(output);\n this._result = { ...rest, output: parsed } as SessionResult<T>;\n return this._result;\n }\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) =>\n setTimeout(r, Math.min(this._interval, remaining)),\n );\n }\n\n throw new Error(\n `Session ${sessionId} did not complete within ${this._timeout}ms`,\n );\n }\n\n /**\n * Enable `for await (const msg of client.run(...))` — yields messages as they appear.\n * After iteration, `.result` contains the final SessionResult.\n */\n async *[Symbol.asyncIterator](): AsyncGenerator<MessageResponse> {\n const sessionId = await this._ensureSessionId();\n let cursor: string | undefined = this._options?._startCursor;\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const resp = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n for (const msg of resp.messages) {\n yield msg;\n cursor = msg.id;\n }\n\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n // Drain all remaining messages (may be multiple pages)\n while (true) {\n const page = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n if (!page.messages.length) break;\n for (const msg of page.messages) {\n yield msg;\n cursor = msg.id;\n }\n }\n const { output, ...rest } = session;\n this._result = { ...rest, output: this._parseOutput(output) } as SessionResult<T>;\n return;\n }\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(this._interval, remaining)));\n }\n\n throw new Error(`Session ${sessionId} did not complete within ${this._timeout}ms`);\n }\n\n private _parseOutput(output: unknown): T {\n if (output == null) return null as T;\n if (!this._schema) return output as unknown as T;\n const raw = typeof output === \"string\" ? JSON.parse(output) : output;\n return this._schema.parse(raw);\n }\n}\n"],"mappings":"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","names":["promise"]}
|
|
1
|
+
{"version":3,"sources":["../src/v3/client.ts","../src/v3/resources/billing.ts","../src/v3/resources/browsers.ts","../src/v3/resources/profiles.ts","../src/v3/resources/sessions.ts","../src/v3/resources/workspaces.ts","../src/v3/helpers.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { HttpClient } from \"../core/http.js\";\nimport {\n X402_BASE_URL_DEFAULT,\n type X402Client,\n wrapFetchWithX402,\n x402ClientFromPrivateKey,\n} from \"../core/x402.js\";\nimport { Billing } from \"./resources/billing.js\";\nimport { Browsers } from \"./resources/browsers.js\";\nimport { Profiles } from \"./resources/profiles.js\";\nimport { Sessions } from \"./resources/sessions.js\";\nimport { Workspaces } from \"./resources/workspaces.js\";\nimport { SessionRun } from \"./helpers.js\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { RunOptions } from \"./helpers.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n\nconst DEFAULT_BASE_URL = \"https://api.browser-use.com/api/v3\";\n\nexport interface BrowserUseOptions {\n apiKey?: string;\n baseUrl?: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Use your own LLM API key configured in Browser Use project settings for v3 agent runs.\n */\n useOwnKey?: boolean;\n /**\n * Pre-built x402 client (advanced — for custom signers / multi-network).\n * If set, the SDK uses pay-per-request authentication via USDC instead of\n * an API key. Requires the optional peer deps `@x402/fetch`, `@x402/evm`,\n * and `viem`.\n */\n x402?: X402Client;\n /**\n * EVM wallet private key for x402 mode. Equivalent to building an x402\n * client from this key and passing it as `x402`. Falls back to\n * `BROWSER_USE_X402_PRIVATE_KEY`.\n */\n x402PrivateKey?: string;\n}\n\nexport type RunSessionOptions = Partial<Omit<RunTaskRequest, \"task\">> &\n RunOptions & { schema?: z.ZodType };\n\nexport class BrowserUse {\n readonly billing: Billing;\n readonly browsers: Browsers;\n readonly profiles: Profiles;\n readonly sessions: Sessions;\n readonly workspaces: Workspaces;\n\n private readonly http: HttpClient;\n\n constructor(options: BrowserUseOptions = {}) {\n const x402PrivateKey =\n options.x402PrivateKey ?? process.env.BROWSER_USE_X402_PRIVATE_KEY;\n\n if (options.x402 || x402PrivateKey) {\n // x402 mode — defer x402 client + wrapped fetch resolution to first request.\n // If apiKey is also set, it's forwarded as a header so the backend\n // credits the API key's project (top-up mode) instead of one keyed\n // to the wallet.\n const topupKey = options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n const fetchPromise = (async () => {\n const x402Client = options.x402 ?? (await x402ClientFromPrivateKey(x402PrivateKey!));\n return wrapFetchWithX402(globalThis.fetch, x402Client);\n })();\n // Suppress unhandled-rejection warnings if the user constructs the client\n // but never makes a request\n fetchPromise.catch(() => {});\n this.http = new HttpClient({\n apiKey: topupKey,\n baseUrl: options.baseUrl ?? X402_BASE_URL_DEFAULT,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n fetch: fetchPromise,\n });\n } else {\n const apiKey =\n options.apiKey ?? process.env.BROWSER_USE_API_KEY ?? \"\";\n if (!apiKey) {\n throw new Error(\n \"No credentials provided. Pass apiKey / set BROWSER_USE_API_KEY, \" +\n \"or pass x402PrivateKey / set BROWSER_USE_X402_PRIVATE_KEY for \" +\n \"pay-per-request access via USDC.\",\n );\n }\n this.http = new HttpClient({\n apiKey,\n baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,\n maxRetries: options.maxRetries,\n timeout: options.timeout,\n });\n }\n\n this.billing = new Billing(this.http);\n this.browsers = new Browsers(this.http);\n this.profiles = new Profiles(this.http);\n this.sessions = new Sessions(this.http, { useOwnKey: options.useOwnKey });\n this.workspaces = new Workspaces(this.http);\n }\n\n /**\n * Create a session and run a task. `await` the result for a typed SessionResult.\n *\n * ```ts\n * // Simple — just get the output\n * const result = await client.run(\"Find the top HN post\");\n * console.log(result.output);\n *\n * // Structured output (Zod)\n * const result = await client.run(\"Find product info\", { schema: ProductSchema });\n * console.log(result.output.name); // fully typed\n * ```\n */\n run(task: string, options?: Omit<RunSessionOptions, \"schema\">): SessionRun<string>;\n run<T extends z.ZodType>(task: string, options: RunSessionOptions & { schema: T }): SessionRun<z.output<T>>;\n run(task: string, options?: RunSessionOptions): SessionRun<any> {\n const { schema, timeout, interval, ...rest } = options ?? {};\n const body = { task, ...rest } as RunTaskRequest;\n if (body.proxyCountryCode) {\n body.proxyCountryCode = body.proxyCountryCode.toLowerCase() as any;\n }\n if (schema) {\n if (typeof schema !== \"object\" || !(\"_zod\" in schema || \"_def\" in schema)) {\n throw new Error(\n \"schema must be a Zod schema (e.g. z.object({...})). \" +\n \"Make sure you are using Zod v4: npm install zod@4\"\n );\n }\n body.outputSchema = z.toJSONSchema(schema) as Record<string, unknown>;\n }\n // Auto keep_alive when dispatching to an existing session\n if (body.sessionId && body.keepAlive === undefined) {\n body.keepAlive = true;\n }\n // For follow-up runs on an existing session, snapshot the latest message\n // cursor before creating the new task so the iterator skips old messages.\n if (body.sessionId) {\n const sid = body.sessionId;\n const sessions = this.sessions;\n let startCursor: string | undefined;\n const promise = sessions\n .messages(sid, { limit: 1 })\n .then((resp) => {\n const last = resp.messages[resp.messages.length - 1];\n startCursor = last?.id;\n })\n .then(() => sessions.create(body));\n // startCursor is set before createPromise resolves, so the iterator\n // (which awaits _ensureSessionId first) will see the correct value.\n return new SessionRun(promise, this.sessions, schema, {\n timeout,\n interval,\n get _startCursor() { return startCursor; },\n });\n }\n const promise = this.sessions.create(body);\n return new SessionRun(promise, this.sessions, schema, { timeout, interval });\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype AccountView = components[\"schemas\"][\"AccountView\"];\n\nexport class Billing {\n constructor(private readonly http: HttpClient) {}\n\n /** Get account billing information. */\n account(): Promise<AccountView> {\n return this.http.get<AccountView>(\"/billing/account\");\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype CreateBrowserSessionRequest = components[\"schemas\"][\"CreateBrowserSessionRequest\"];\ntype BrowserSessionItemView = components[\"schemas\"][\"BrowserSessionItemView\"];\ntype BrowserSessionView = components[\"schemas\"][\"BrowserSessionView\"];\ntype BrowserSessionListResponse = components[\"schemas\"][\"BrowserSessionListResponse\"];\ntype UpdateBrowserSessionRequest = components[\"schemas\"][\"UpdateBrowserSessionRequest\"];\ntype BrowserDownloadListResponse = components[\"schemas\"][\"BrowserDownloadListResponse\"];\n\nexport interface BrowserListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface BrowserDownloadsParams {\n limit?: number;\n cursor?: string;\n includeUrls?: boolean;\n}\n\nexport class Browsers {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a standalone browser session. */\n create(body: Partial<CreateBrowserSessionRequest> = {}): Promise<BrowserSessionItemView> {\n return this.http.post<BrowserSessionItemView>(\"/browsers\", body);\n }\n\n /** List browser sessions for the authenticated project. */\n list(params?: BrowserListParams): Promise<BrowserSessionListResponse> {\n return this.http.get<BrowserSessionListResponse>(\"/browsers\", params as Record<string, unknown>);\n }\n\n /** Get browser session details. */\n get(sessionId: string): Promise<BrowserSessionView> {\n return this.http.get<BrowserSessionView>(`/browsers/${sessionId}`);\n }\n\n /** Update a browser session (e.g. stop it). */\n update(sessionId: string, body: UpdateBrowserSessionRequest): Promise<BrowserSessionView> {\n return this.http.patch<BrowserSessionView>(`/browsers/${sessionId}`, body);\n }\n\n /** Stop a browser session. Convenience wrapper around update. */\n stop(sessionId: string): Promise<BrowserSessionView> {\n return this.update(sessionId, { action: \"stop\" });\n }\n\n /** List files the browser downloaded to S3 during the session. */\n downloads(sessionId: string, params?: BrowserDownloadsParams): Promise<BrowserDownloadListResponse> {\n return this.http.get<BrowserDownloadListResponse>(\n `/browsers/${sessionId}/downloads`,\n params as Record<string, unknown>,\n );\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype ProfileView = components[\"schemas\"][\"ProfileView\"];\ntype ProfileListResponse = components[\"schemas\"][\"ProfileListResponse\"];\ntype ProfileCreateRequest = components[\"schemas\"][\"ProfileCreateRequest\"];\ntype ProfileUpdateRequest = components[\"schemas\"][\"ProfileUpdateRequest\"];\n\nexport interface ProfileListParams {\n query?: string;\n page?: number;\n page_size?: number;\n}\n\nexport class Profiles {\n constructor(private readonly http: HttpClient) {}\n\n /** Create a browser profile. */\n create(body?: ProfileCreateRequest): Promise<ProfileView> {\n return this.http.post<ProfileView>(\"/profiles\", body);\n }\n\n /** List profiles for the authenticated project. */\n list(params?: ProfileListParams): Promise<ProfileListResponse> {\n return this.http.get<ProfileListResponse>(\"/profiles\", params as Record<string, unknown>);\n }\n\n /** Get profile details. */\n get(profileId: string): Promise<ProfileView> {\n return this.http.get<ProfileView>(`/profiles/${profileId}`);\n }\n\n /** Update a profile. */\n update(profileId: string, body: ProfileUpdateRequest): Promise<ProfileView> {\n return this.http.patch<ProfileView>(`/profiles/${profileId}`, body);\n }\n\n /** Delete a profile. */\n delete(profileId: string): Promise<void> {\n return this.http.delete<void>(`/profiles/${profileId}`);\n }\n}\n","import type { HttpClient } from \"../../core/http.js\";\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype RunTaskRequest = components[\"schemas\"][\"app__endpoints__api__v3__sessions__views__RunTaskRequest\"];\n/** All fields optional — omit `task` to create an idle session. */\nexport type CreateSessionBody = Partial<RunTaskRequest>;\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype SessionListResponse = components[\"schemas\"][\"SessionListResponse\"];\ntype StopSessionRequest = components[\"schemas\"][\"StopSessionRequest\"];\ntype MessageListResponse = components[\"schemas\"][\"MessageListResponse\"];\n\nexport interface SessionListParams {\n page?: number;\n page_size?: number;\n}\n\nexport interface SessionMessagesParams {\n after?: string | null;\n before?: string | null;\n limit?: number;\n}\n\nexport interface SessionsOptions {\n useOwnKey?: boolean;\n}\n\nexport class Sessions {\n constructor(\n private readonly http: HttpClient,\n private readonly options: SessionsOptions = {},\n ) {}\n\n /** Create a session and optionally dispatch a task. */\n create(body?: CreateSessionBody): Promise<SessionResponse> {\n const requestBody = { ...(body ?? {}) };\n if (\n this.options.useOwnKey !== undefined &&\n requestBody.useOwnKey === undefined\n ) {\n requestBody.useOwnKey = this.options.useOwnKey;\n }\n return this.http.post<SessionResponse>(\"/sessions\", requestBody);\n }\n\n /** List sessions for the authenticated project. */\n list(params?: SessionListParams): Promise<SessionListResponse> {\n return this.http.get<SessionListResponse>(\"/sessions\", params as Record<string, unknown>);\n }\n\n /** Get session details. */\n get(sessionId: string): Promise<SessionResponse> {\n return this.http.get<SessionResponse>(`/sessions/${sessionId}`);\n }\n\n /** Stop a session or the running task. */\n stop(sessionId: string, body?: StopSessionRequest): Promise<SessionResponse> {\n return this.http.post<SessionResponse>(`/sessions/${sessionId}/stop`, body);\n }\n\n /** Soft-delete a session. */\n delete(sessionId: string): Promise<void> {\n return this.http.delete<void>(`/sessions/${sessionId}`);\n }\n\n /** List messages for a session with cursor-based pagination. */\n messages(sessionId: string, params?: SessionMessagesParams): Promise<MessageListResponse> {\n return this.http.get<MessageListResponse>(\n `/sessions/${sessionId}/messages`,\n params as Record<string, unknown>,\n );\n }\n\n /**\n * Poll until recording URLs are available. Returns presigned MP4 URLs.\n *\n * Returns an empty array if no recording was produced (e.g. the agent\n * answered without opening a browser, or recording was not enabled).\n */\n async waitForRecording(\n sessionId: string,\n options?: { timeout?: number; interval?: number },\n ): Promise<string[]> {\n const timeout = options?.timeout ?? 15_000;\n const interval = options?.interval ?? 2_000;\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const session = await this.get(sessionId);\n if (session.recordingUrls?.length) return session.recordingUrls;\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(interval, remaining)));\n }\n return [];\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, statSync } from \"fs\";\nimport { basename, dirname, extname, join, resolve } from \"path\";\nimport type { HttpClient } from \"../../core/http.js\";\n\nfunction safeJoin(base: string, untrusted: string): string {\n const baseResolved = resolve(base) + \"/\";\n const resolved = resolve(base, untrusted);\n if (resolved !== resolve(base) && !resolved.startsWith(baseResolved)) {\n throw new Error(`Path traversal detected: ${untrusted}`);\n }\n return resolved;\n}\n\nconst MIME_TYPES: Record<string, string> = {\n \".csv\": \"text/csv\",\n \".json\": \"application/json\",\n \".txt\": \"text/plain\",\n \".md\": \"text/markdown\",\n \".html\": \"text/html\",\n \".xml\": \"application/xml\",\n \".yaml\": \"application/yaml\",\n \".yml\": \"application/yaml\",\n \".pdf\": \"application/pdf\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".mp4\": \"video/mp4\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".zip\": \"application/zip\",\n \".gz\": \"application/gzip\",\n \".tar\": \"application/x-tar\",\n \".xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \".xls\": \"application/vnd.ms-excel\",\n \".docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".doc\": \"application/msword\",\n \".pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n};\n\nfunction guessContentType(path: string): string {\n return MIME_TYPES[extname(path).toLowerCase()] ?? \"application/octet-stream\";\n}\nimport type { components } from \"../../generated/v3/types.js\";\n\ntype WorkspaceView = components[\"schemas\"][\"WorkspaceView\"];\ntype WorkspaceListResponse = components[\"schemas\"][\"WorkspaceListResponse\"];\ntype WorkspaceCreateRequest = components[\"schemas\"][\"WorkspaceCreateRequest\"];\ntype WorkspaceUpdateRequest = components[\"schemas\"][\"WorkspaceUpdateRequest\"];\ntype FileListResponse = components[\"schemas\"][\"FileListResponse\"];\ntype FileUploadRequest = components[\"schemas\"][\"FileUploadRequest\"];\ntype FileUploadResponse = components[\"schemas\"][\"FileUploadResponse\"];\n\nexport interface WorkspaceListParams {\n pageSize?: number;\n pageNumber?: number;\n}\n\nexport interface WorkspaceFilesParams {\n prefix?: string;\n limit?: number;\n cursor?: string | null;\n includeUrls?: boolean;\n shallow?: boolean;\n}\n\nexport class Workspaces {\n constructor(private readonly http: HttpClient) {}\n\n /** List workspaces for the authenticated project. */\n list(params?: WorkspaceListParams): Promise<WorkspaceListResponse> {\n return this.http.get<WorkspaceListResponse>(\"/workspaces\", params as Record<string, unknown>);\n }\n\n /** Create a new workspace. */\n create(body?: WorkspaceCreateRequest): Promise<WorkspaceView> {\n return this.http.post<WorkspaceView>(\"/workspaces\", body);\n }\n\n /** Get workspace details. */\n get(workspaceId: string): Promise<WorkspaceView> {\n return this.http.get<WorkspaceView>(`/workspaces/${workspaceId}`);\n }\n\n /** Update a workspace. */\n update(workspaceId: string, body: WorkspaceUpdateRequest): Promise<WorkspaceView> {\n return this.http.patch<WorkspaceView>(`/workspaces/${workspaceId}`, body);\n }\n\n /** Delete a workspace and its data. */\n delete(workspaceId: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}`);\n }\n\n /** List files in a workspace. */\n files(workspaceId: string, params?: WorkspaceFilesParams): Promise<FileListResponse> {\n return this.http.get<FileListResponse>(\n `/workspaces/${workspaceId}/files`,\n params as Record<string, unknown>,\n );\n }\n\n /** Get presigned upload URLs for workspace files. */\n uploadFiles(workspaceId: string, body: FileUploadRequest, query?: { prefix?: string }): Promise<FileUploadResponse> {\n return this.http.post<FileUploadResponse>(\n `/workspaces/${workspaceId}/files/upload`,\n body,\n query as Record<string, unknown>,\n );\n }\n\n /** Delete a file from a workspace. */\n deleteFile(workspaceId: string, path: string): Promise<void> {\n return this.http.delete<void>(`/workspaces/${workspaceId}/files`, { path });\n }\n\n /** Get storage usage for a workspace. */\n size(workspaceId: string): Promise<unknown> {\n return this.http.get<unknown>(`/workspaces/${workspaceId}/size`);\n }\n\n /**\n * Upload local files to a workspace. Returns the list of remote paths.\n *\n * ```ts\n * await client.workspaces.upload(wsId, \"data.csv\", \"config.json\");\n * await client.workspaces.upload(wsId, \"data.csv\", { prefix: \"uploads/\" });\n * ```\n */\n async upload(workspaceId: string, ...args: (string | { prefix?: string })[]): Promise<string[]> {\n let prefix: string | undefined;\n const paths: string[] = [];\n for (const arg of args) {\n if (typeof arg === \"string\") {\n paths.push(arg);\n } else if (typeof arg === \"object\" && arg !== null) {\n prefix = arg.prefix;\n }\n }\n if (paths.length === 0) {\n throw new Error(\"At least one file path is required\");\n }\n const items = paths.map((p) => ({\n name: basename(p),\n contentType: guessContentType(p),\n size: statSync(p).size,\n }));\n const resp = await this.uploadFiles(workspaceId, { files: items }, prefix ? { prefix } : undefined);\n for (let i = 0; i < paths.length; i++) {\n const body = readFileSync(paths[i]);\n const res = await fetch(resp.files[i].uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": items[i].contentType },\n body,\n });\n if (!res.ok) throw new Error(`Upload failed: ${res.status} ${res.statusText}`);\n }\n return resp.files.map((f) => f.path);\n }\n\n /**\n * Download a single file from a workspace. Returns the local path.\n *\n * ```ts\n * const local = await client.workspaces.download(wsId, \"uploads/data.csv\", { to: \"./data.csv\" });\n * ```\n */\n async download(workspaceId: string, path: string, options?: { to?: string }): Promise<string> {\n const fileList = await this.files(workspaceId, { prefix: path, includeUrls: true });\n const match = fileList.files?.find((f) => f.path === path);\n if (!match) throw new Error(`File not found in workspace: ${path}`);\n const dest = options?.to ?? basename(match.path);\n mkdirSync(dirname(dest), { recursive: true });\n const resp = await fetch(match.url!);\n if (!resp.ok) throw new Error(`Download failed: ${resp.status}`);\n writeFileSync(dest, Buffer.from(await resp.arrayBuffer()));\n return dest;\n }\n\n /**\n * Download all files from a workspace. Returns list of local paths.\n *\n * ```ts\n * const paths = await client.workspaces.downloadAll(wsId, { to: \"./output\" });\n * ```\n */\n async downloadAll(workspaceId: string, options?: { to?: string; prefix?: string }): Promise<string[]> {\n const destDir = options?.to ?? \".\";\n mkdirSync(destDir, { recursive: true });\n const results: string[] = [];\n let cursor: string | undefined;\n do {\n const fileList = await this.files(workspaceId, {\n prefix: options?.prefix,\n includeUrls: true,\n cursor,\n });\n for (const f of fileList.files ?? []) {\n const local = safeJoin(destDir, f.path);\n mkdirSync(dirname(local), { recursive: true });\n const resp = await fetch(f.url!);\n if (!resp.ok) throw new Error(`Download failed for ${f.path}: ${resp.status}`);\n writeFileSync(local, Buffer.from(await resp.arrayBuffer()));\n results.push(local);\n }\n cursor = fileList.hasMore ? (fileList.nextCursor ?? undefined) : undefined;\n } while (cursor);\n return results;\n }\n}\n","import type { z } from \"zod\";\nimport type { components } from \"../generated/v3/types.js\";\nimport type { Sessions } from \"./resources/sessions.js\";\n\ntype SessionResponse = components[\"schemas\"][\"SessionResponse\"];\ntype MessageResponse = components[\"schemas\"][\"MessageResponse\"];\n\nconst TERMINAL_STATUSES = new Set([\"idle\", \"stopped\", \"timed_out\", \"error\"]);\n\nexport interface RunOptions {\n /** Maximum time to wait in milliseconds. Default: 14_400_000 (4 hours). */\n timeout?: number;\n /** Polling interval in milliseconds. Default: 2_000. */\n interval?: number;\n /** @internal Starting message cursor for follow-up runs on an existing session. */\n _startCursor?: string;\n}\n\n/** Session result with typed output. All SessionResponse fields are directly accessible. */\nexport type SessionResult<T = string | null> = Omit<SessionResponse, \"output\"> & { output: T };\n\n/**\n * Dual-purpose session handle: `await` it for a typed SessionResult,\n * or access `.result` for the full SessionResult after resolution.\n */\nexport class SessionRun<T = string> implements PromiseLike<SessionResult<T>> {\n private readonly _createPromise: Promise<SessionResponse>;\n private readonly _sessions: Sessions;\n private readonly _schema?: z.ZodType<T>;\n private readonly _timeout: number;\n private readonly _interval: number;\n private readonly _options?: RunOptions;\n private _sessionId: string | null = null;\n private _result: SessionResult<T> | null = null;\n\n constructor(\n createPromise: Promise<SessionResponse>,\n sessions: Sessions,\n schema?: z.ZodType<T>,\n options?: RunOptions,\n ) {\n this._createPromise = createPromise;\n this._sessions = sessions;\n this._schema = schema;\n this._timeout = options?.timeout ?? 14_400_000;\n this._interval = options?.interval ?? 2_000;\n this._options = options;\n }\n\n /** The session ID, available after task creation resolves. */\n get sessionId(): string | null {\n return this._sessionId;\n }\n\n /** The full SessionResult, available after polling completes. */\n get result(): SessionResult<T> | null {\n return this._result;\n }\n\n /** Enable `await client.run(...)` — polls until terminal, returns SessionResult. */\n then<R1 = SessionResult<T>, R2 = never>(\n onFulfilled?:\n | ((value: SessionResult<T>) => R1 | PromiseLike<R1>)\n | null,\n onRejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null,\n ): Promise<R1 | R2> {\n return this._waitForOutput().then(onFulfilled, onRejected);\n }\n\n private async _ensureSessionId(): Promise<string> {\n if (this._sessionId) return this._sessionId;\n const created = await this._createPromise;\n this._sessionId = created.id;\n return this._sessionId;\n }\n\n /** Poll session until terminal, return SessionResult. */\n private async _waitForOutput(): Promise<SessionResult<T>> {\n const sessionId = await this._ensureSessionId();\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n const { output, ...rest } = session;\n const parsed = this._parseOutput(output);\n this._result = { ...rest, output: parsed } as SessionResult<T>;\n return this._result;\n }\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) =>\n setTimeout(r, Math.min(this._interval, remaining)),\n );\n }\n\n throw new Error(\n `Session ${sessionId} did not complete within ${this._timeout}ms`,\n );\n }\n\n /**\n * Enable `for await (const msg of client.run(...))` — yields messages as they appear.\n * After iteration, `.result` contains the final SessionResult.\n */\n async *[Symbol.asyncIterator](): AsyncGenerator<MessageResponse> {\n const sessionId = await this._ensureSessionId();\n let cursor: string | undefined = this._options?._startCursor;\n const deadline = Date.now() + this._timeout;\n\n while (Date.now() < deadline) {\n const resp = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n for (const msg of resp.messages) {\n yield msg;\n cursor = msg.id;\n }\n\n const session = await this._sessions.get(sessionId);\n if (TERMINAL_STATUSES.has(session.status)) {\n // Drain all remaining messages (may be multiple pages)\n while (true) {\n const page = await this._sessions.messages(sessionId, { after: cursor, limit: 100 });\n if (!page.messages.length) break;\n for (const msg of page.messages) {\n yield msg;\n cursor = msg.id;\n }\n }\n const { output, ...rest } = session;\n this._result = { ...rest, output: this._parseOutput(output) } as SessionResult<T>;\n return;\n }\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n await new Promise((r) => setTimeout(r, Math.min(this._interval, remaining)));\n }\n\n throw new Error(`Session ${sessionId} did not complete within ${this._timeout}ms`);\n }\n\n private _parseOutput(output: unknown): T {\n if (output == null) return null as T;\n if (!this._schema) return output as unknown as T;\n const raw = typeof output === \"string\" ? JSON.parse(output) : output;\n return this._schema.parse(raw);\n }\n}\n"],"mappings":"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","names":["promise"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-use-sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.1",
|
|
4
4
|
"description": "Official TypeScript SDK for the Browser Use API",
|
|
5
5
|
"author": "Browser Use",
|
|
6
6
|
"license": "MIT",
|
|
@@ -69,9 +69,15 @@
|
|
|
69
69
|
"viem": "^2.48.0"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
72
|
-
"@x402/evm": {
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
"@x402/evm": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@x402/fetch": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"viem": {
|
|
79
|
+
"optional": true
|
|
80
|
+
}
|
|
75
81
|
},
|
|
76
82
|
"packageManager": "pnpm@10.23.0+sha512.21c4e5698002ade97e4efe8b8b4a89a8de3c85a37919f957e7a0f30f38fbc5bbdd05980ffe29179b2fb6e6e691242e098d945d1601772cad0fef5fb6411e2a4b"
|
|
77
83
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/chunk-4BAZFOC2.cjs","../src/core/errors.ts","../src/core/http.ts","../src/core/x402.ts"],"names":[],"mappings":"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","file":"/Users/sauravpanda/Github/LLMs/Browser-Use/sdk/browser-use-node/dist/chunk-4BAZFOC2.cjs","sourcesContent":[null,"export class BrowserUseError extends Error {\n readonly statusCode: number;\n readonly detail: unknown;\n\n constructor(statusCode: number, message: string, detail?: unknown) {\n super(message);\n this.name = \"BrowserUseError\";\n this.statusCode = statusCode;\n this.detail = detail;\n }\n}\n","import { BrowserUseError } from \"./errors.js\";\nimport type { FetchLike } from \"./x402.js\";\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Optional custom fetch implementation. May be a sync value or a Promise\n * (for lazy resolution of e.g. x402-wrapped fetch). When set, replaces\n * `globalThis.fetch`. The `X-Browser-Use-API-Key` header is still sent if\n * `apiKey` is non-empty (top-up mode in x402); pass `apiKey: \"\"` to omit.\n */\n fetch?: FetchLike | Promise<FetchLike>;\n}\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly maxRetries: number;\n private readonly timeout: number;\n private readonly fetchPromise: Promise<FetchLike>;\n private readonly useApiKeyHeader: boolean;\n\n constructor(options: HttpClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.maxRetries = options.maxRetries ?? 3;\n this.timeout = options.timeout ?? 30_000;\n this.fetchPromise = Promise.resolve(\n options.fetch ?? ((input, init) => fetch(input, init)),\n );\n // Send the API key header whenever apiKey is non-empty. In x402 mode\n // an empty apiKey means \"accountless\" (wallet is identity); a non-empty\n // apiKey means \"top up the existing key's project\".\n this.useApiKeyHeader = options.apiKey !== \"\";\n }\n\n async request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n query?: Record<string, unknown>;\n signal?: AbortSignal;\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (options?.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {};\n if (this.useApiKeyHeader) {\n headers[\"X-Browser-Use-API-Key\"] = this.apiKey;\n }\n if (options?.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = Math.min(1000 * 2 ** (attempt - 1), 10_000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n const controller = new AbortController();\n const timeoutId = options?.signal\n ? undefined\n : setTimeout(() => controller.abort(), this.timeout);\n\n // Combine user signal with internal timeout when both are present\n const signal = options?.signal ?? controller.signal;\n\n try {\n const fetchImpl = await this.fetchPromise;\n const response = await fetchImpl(url.toString(), {\n method,\n headers,\n body: options?.body !== undefined ? JSON.stringify(options.body) : undefined,\n signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n if (response.status === 204) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n const shouldRetry =\n response.status === 429 &&\n attempt < this.maxRetries;\n\n if (shouldRetry) {\n continue;\n }\n\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n /* ignore parse errors */\n }\n const raw =\n typeof errorBody === \"object\" && errorBody !== null\n ? \"message\" in errorBody\n ? (errorBody as Record<string, unknown>).message\n : \"detail\" in errorBody\n ? (errorBody as Record<string, unknown>).detail\n : undefined\n : undefined;\n const message =\n raw === undefined\n ? `HTTP ${response.status}`\n : typeof raw === \"string\"\n ? raw\n : JSON.stringify(raw);\n throw new BrowserUseError(response.status, message, errorBody);\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n throw new Error(\"Unreachable: retry loop exhausted\");\n }\n\n get<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n post<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"POST\", path, { body, query });\n }\n\n patch<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"PATCH\", path, { body, query });\n }\n\n delete<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"DELETE\", path, { query });\n }\n}\n","/**\n * Helpers for the optional x402 (pay-per-request) integration.\n *\n * x402 is an HTTP payment protocol: instead of an API key, requests are\n * authenticated by signing a small USDC payment. See the docs at\n * `cloud/guides/x402` and https://www.x402.org for details.\n *\n * The peer deps `@x402/fetch`, `@x402/evm`, and `viem` are optional. They are\n * imported lazily so users who only use API-key auth never pay the cost.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type X402Client = any;\nexport type FetchLike = (\n input: RequestInfo | URL,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport const X402_BASE_URL_DEFAULT = \"https://x402.api.browser-use.com/api/v3\";\nexport const X402_BASE_URL_DEFAULT_V2 = \"https://x402.api.browser-use.com/api/v2\";\n\nconst MISSING_X402 =\n \"x402 mode requires the optional peer deps. Install them with: \" +\n \"npm install @x402/fetch @x402/evm viem \" +\n \"(or the equivalent for pnpm/yarn).\";\n\n/** Build a ready-to-use x402 client from an EVM private key (`0x...`). */\nexport async function x402ClientFromPrivateKey(\n privateKey: `0x${string}` | string,\n): Promise<X402Client> {\n let viem;\n let fetchPkg;\n let evmPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n viem = await import(\"viem/accounts\");\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n // @ts-ignore - optional peer dep, may not be installed\n evmPkg = await import(\"@x402/evm\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n\n const key = privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`;\n const signer = viem.privateKeyToAccount(key as `0x${string}`);\n const client = new fetchPkg.x402Client();\n client.register(\"eip155:*\", new evmPkg.ExactEvmScheme(signer));\n return client;\n}\n\n/** Wrap a fetch with x402 payment handling. */\nexport async function wrapFetchWithX402(\n fetch: FetchLike,\n x402Client: X402Client,\n): Promise<FetchLike> {\n let fetchPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n return fetchPkg.wrapFetchWithPayment(fetch, x402Client);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/errors.ts","../src/core/http.ts","../src/core/x402.ts"],"sourcesContent":["export class BrowserUseError extends Error {\n readonly statusCode: number;\n readonly detail: unknown;\n\n constructor(statusCode: number, message: string, detail?: unknown) {\n super(message);\n this.name = \"BrowserUseError\";\n this.statusCode = statusCode;\n this.detail = detail;\n }\n}\n","import { BrowserUseError } from \"./errors.js\";\nimport type { FetchLike } from \"./x402.js\";\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries?: number;\n timeout?: number;\n /**\n * Optional custom fetch implementation. May be a sync value or a Promise\n * (for lazy resolution of e.g. x402-wrapped fetch). When set, replaces\n * `globalThis.fetch`. The `X-Browser-Use-API-Key` header is still sent if\n * `apiKey` is non-empty (top-up mode in x402); pass `apiKey: \"\"` to omit.\n */\n fetch?: FetchLike | Promise<FetchLike>;\n}\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly maxRetries: number;\n private readonly timeout: number;\n private readonly fetchPromise: Promise<FetchLike>;\n private readonly useApiKeyHeader: boolean;\n\n constructor(options: HttpClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.maxRetries = options.maxRetries ?? 3;\n this.timeout = options.timeout ?? 30_000;\n this.fetchPromise = Promise.resolve(\n options.fetch ?? ((input, init) => fetch(input, init)),\n );\n // Send the API key header whenever apiKey is non-empty. In x402 mode\n // an empty apiKey means \"accountless\" (wallet is identity); a non-empty\n // apiKey means \"top up the existing key's project\".\n this.useApiKeyHeader = options.apiKey !== \"\";\n }\n\n async request<T>(\n method: string,\n path: string,\n options?: {\n body?: unknown;\n query?: Record<string, unknown>;\n signal?: AbortSignal;\n },\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n if (options?.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const headers: Record<string, string> = {};\n if (this.useApiKeyHeader) {\n headers[\"X-Browser-Use-API-Key\"] = this.apiKey;\n }\n if (options?.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = Math.min(1000 * 2 ** (attempt - 1), 10_000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n const controller = new AbortController();\n const timeoutId = options?.signal\n ? undefined\n : setTimeout(() => controller.abort(), this.timeout);\n\n // Combine user signal with internal timeout when both are present\n const signal = options?.signal ?? controller.signal;\n\n try {\n const fetchImpl = await this.fetchPromise;\n const response = await fetchImpl(url.toString(), {\n method,\n headers,\n body: options?.body !== undefined ? JSON.stringify(options.body) : undefined,\n signal,\n });\n\n clearTimeout(timeoutId);\n\n if (response.ok) {\n if (response.status === 204) {\n return undefined as T;\n }\n return (await response.json()) as T;\n }\n\n const shouldRetry =\n response.status === 429 &&\n attempt < this.maxRetries;\n\n if (shouldRetry) {\n continue;\n }\n\n let errorBody: unknown;\n try {\n errorBody = await response.json();\n } catch {\n /* ignore parse errors */\n }\n const raw =\n typeof errorBody === \"object\" && errorBody !== null\n ? \"message\" in errorBody\n ? (errorBody as Record<string, unknown>).message\n : \"detail\" in errorBody\n ? (errorBody as Record<string, unknown>).detail\n : undefined\n : undefined;\n const message =\n raw === undefined\n ? `HTTP ${response.status}`\n : typeof raw === \"string\"\n ? raw\n : JSON.stringify(raw);\n throw new BrowserUseError(response.status, message, errorBody);\n } catch (error) {\n clearTimeout(timeoutId);\n throw error;\n }\n }\n\n throw new Error(\"Unreachable: retry loop exhausted\");\n }\n\n get<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"GET\", path, { query });\n }\n\n post<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"POST\", path, { body, query });\n }\n\n patch<T>(path: string, body?: unknown, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"PATCH\", path, { body, query });\n }\n\n delete<T>(path: string, query?: Record<string, unknown>): Promise<T> {\n return this.request<T>(\"DELETE\", path, { query });\n }\n}\n","/**\n * Helpers for the optional x402 (pay-per-request) integration.\n *\n * x402 is an HTTP payment protocol: instead of an API key, requests are\n * authenticated by signing a small USDC payment. See the docs at\n * `cloud/guides/x402` and https://www.x402.org for details.\n *\n * The peer deps `@x402/fetch`, `@x402/evm`, and `viem` are optional. They are\n * imported lazily so users who only use API-key auth never pay the cost.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type X402Client = any;\nexport type FetchLike = (\n input: RequestInfo | URL,\n init?: RequestInit,\n) => Promise<Response>;\n\nexport const X402_BASE_URL_DEFAULT = \"https://x402.api.browser-use.com/api/v3\";\nexport const X402_BASE_URL_DEFAULT_V2 = \"https://x402.api.browser-use.com/api/v2\";\n\nconst MISSING_X402 =\n \"x402 mode requires the optional peer deps. Install them with: \" +\n \"npm install @x402/fetch @x402/evm viem \" +\n \"(or the equivalent for pnpm/yarn).\";\n\n/** Build a ready-to-use x402 client from an EVM private key (`0x...`). */\nexport async function x402ClientFromPrivateKey(\n privateKey: `0x${string}` | string,\n): Promise<X402Client> {\n let viem;\n let fetchPkg;\n let evmPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n viem = await import(\"viem/accounts\");\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n // @ts-ignore - optional peer dep, may not be installed\n evmPkg = await import(\"@x402/evm\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n\n const key = privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`;\n const signer = viem.privateKeyToAccount(key as `0x${string}`);\n const client = new fetchPkg.x402Client();\n client.register(\"eip155:*\", new evmPkg.ExactEvmScheme(signer));\n return client;\n}\n\n/** Wrap a fetch with x402 payment handling. */\nexport async function wrapFetchWithX402(\n fetch: FetchLike,\n x402Client: X402Client,\n): Promise<FetchLike> {\n let fetchPkg;\n try {\n // @ts-ignore - optional peer dep, may not be installed\n fetchPkg = await import(\"@x402/fetch\");\n } catch (e) {\n throw new Error(MISSING_X402);\n }\n return fetchPkg.wrapFetchWithPayment(fetch, x402Client);\n}\n"],"mappings":"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","names":["fetch"]}
|