@poncho-ai/browser 0.5.0 → 0.6.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @poncho-ai/browser@0.4.0 build /Users/cesar/Dev/latitude/poncho-ai/packages/browser
2
+ > @poncho-ai/browser@0.6.1 build /Users/cesar/Dev/latitude/poncho-ai/packages/browser
3
3
  > tsup src/index.ts --format esm --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -7,8 +7,8 @@
7
7
  CLI tsup v8.5.1
8
8
  CLI Target: es2022
9
9
  ESM Build start
10
- ESM dist/index.js 34.91 KB
11
- ESM ⚡️ Build success in 218ms
10
+ ESM dist/index.js 41.37 KB
11
+ ESM ⚡️ Build success in 83ms
12
12
  DTS Build start
13
- DTS ⚡️ Build success in 5616ms
14
- DTS dist/index.d.ts 12.44 KB
13
+ DTS ⚡️ Build success in 1112ms
14
+ DTS dist/index.d.ts 13.59 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @poncho-ai/browser
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Pass `@sparticuz/chromium` recommended args (--no-sandbox, --disable-gpu, etc.) when launching on serverless platforms. Fixes Chromium sandbox crash on Vercel/Lambda.
8
+
9
+ ## 0.6.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`76294e9`](https://github.com/cesr/poncho-ai/commit/76294e95035bf3abbb19c28871a33f82351c49ec) Thanks [@cesr](https://github.com/cesr)! - Support remote and serverless browser deployments.
14
+
15
+ **@poncho-ai/browser**: Add `provider` and `cdpUrl` config options for cloud browser services (Browserbase, Browser Use, Kernel) and direct CDP connections. Auto-detect `@sparticuz/chromium` on serverless platforms (Vercel, Lambda) and default the profile directory to `/tmp`.
16
+
17
+ **@poncho-ai/cli**: Generate @vercel/nft trace hints for `@poncho-ai/browser` and `@sparticuz/chromium` in the Vercel entry point so dynamically-loaded browser packages are bundled into the serverless function.
18
+
3
19
  ## 0.5.0
4
20
 
5
21
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -64,6 +64,13 @@ interface BrowserConfig {
64
64
  * user-agent, and passes anti-automation Chrome flags. */
65
65
  stealth?: boolean;
66
66
  storagePersistence?: BrowserStoragePersistence;
67
+ /** Cloud browser provider. Requires the provider's API key env var to be set
68
+ * (e.g. `BROWSERBASE_API_KEY` + `BROWSERBASE_PROJECT_ID` for Browserbase).
69
+ * When set, the browser runs remotely instead of launching a local Chromium. */
70
+ provider?: "browserbase" | "browseruse" | "kernel";
71
+ /** Connect to an existing browser via Chrome DevTools Protocol URL or port.
72
+ * Mutually exclusive with `provider`. */
73
+ cdpUrl?: string;
67
74
  }
68
75
 
69
76
  type FrameListener = (frame: BrowserFrame) => void;
@@ -101,6 +108,14 @@ declare class BrowserSession {
101
108
  * CDP Network.setUserAgentOverride is per-target, so call per-tab.
102
109
  */
103
110
  private overrideUserAgentOnPage;
111
+ private get isRemote();
112
+ private get isServerless();
113
+ /**
114
+ * Resolve executablePath and launch args for serverless platforms.
115
+ * When `@sparticuz/chromium` is installed, uses its executable and
116
+ * recommended args (--no-sandbox, --disable-gpu, etc.).
117
+ */
118
+ private resolveServerlessChromium;
104
119
  private launchFreshManager;
105
120
  private ensureManager;
106
121
  private evictOldestTab;
package/dist/index.js CHANGED
@@ -338,26 +338,76 @@ var BrowserSession = class {
338
338
  console.warn("[poncho][browser] Failed to override UA via CDP:", err?.message ?? err);
339
339
  }
340
340
  }
341
+ get isRemote() {
342
+ return !!(this.config.provider || this.config.cdpUrl);
343
+ }
344
+ get isServerless() {
345
+ return !!(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.AWS_EXECUTION_ENV || process.env.SERVERLESS);
346
+ }
347
+ /**
348
+ * Resolve executablePath and launch args for serverless platforms.
349
+ * When `@sparticuz/chromium` is installed, uses its executable and
350
+ * recommended args (--no-sandbox, --disable-gpu, etc.).
351
+ */
352
+ async resolveServerlessChromium() {
353
+ if (this.config.executablePath) return { executablePath: this.config.executablePath };
354
+ if (!this.isServerless) return {};
355
+ try {
356
+ const spec = ["@sparticuz", "chromium"].join("/");
357
+ const mod = await import(
358
+ /* webpackIgnore: true */
359
+ spec
360
+ );
361
+ const chromium = mod.default ?? mod;
362
+ const executablePath = await chromium.executablePath();
363
+ const args = Array.isArray(chromium.args) ? chromium.args : [];
364
+ console.log(`[poncho][browser] Auto-detected @sparticuz/chromium: ${executablePath} (${args.length} args)`);
365
+ return { executablePath, args };
366
+ } catch {
367
+ return {};
368
+ }
369
+ }
341
370
  async launchFreshManager() {
342
371
  const Ctor = await getBrowserManagerCtor();
343
372
  const mgr = new Ctor();
344
373
  const viewport = this.config.viewport ?? { width: 1280, height: 720 };
345
- await mkdir(this.profileDir, { recursive: true });
374
+ const serverless = await this.resolveServerlessChromium();
346
375
  const launchOpts = {
347
376
  action: "launch",
348
377
  headless: this.config.headless ?? true,
349
378
  viewport: { width: viewport.width ?? 1280, height: viewport.height ?? 720 },
350
- executablePath: this.config.executablePath,
351
- profile: this.profileDir
379
+ executablePath: serverless.executablePath
352
380
  };
381
+ if (this.config.cdpUrl) {
382
+ launchOpts.cdpUrl = this.config.cdpUrl;
383
+ console.log(`[poncho][browser] Connecting via CDP: ${this.config.cdpUrl}`);
384
+ } else if (this.config.provider) {
385
+ launchOpts.provider = this.config.provider;
386
+ console.log(`[poncho][browser] Using cloud provider: ${this.config.provider}`);
387
+ } else {
388
+ const profileDir = this.isServerless && !this.config.profileDir ? join(tmpdir(), "poncho-browser", this.sessionId) : this.profileDir;
389
+ await mkdir(profileDir, { recursive: true });
390
+ launchOpts.profile = profileDir;
391
+ }
392
+ const baseArgs = serverless.args ?? [];
353
393
  if (this.stealthEnabled) {
354
394
  const ua = this.stealthUserAgent;
355
395
  launchOpts.userAgent = ua;
356
- launchOpts.args = buildStealthArgs(ua);
396
+ if (!this.isRemote) {
397
+ const stealthArgs = buildStealthArgs(ua);
398
+ const merged = [...baseArgs];
399
+ for (const arg of stealthArgs) {
400
+ if (!merged.includes(arg)) merged.push(arg);
401
+ }
402
+ launchOpts.args = merged;
403
+ }
357
404
  console.log("[poncho][browser] Launching with stealth mode enabled (UA: " + ua + ")");
358
405
  } else if (this.config.userAgent) {
359
406
  launchOpts.userAgent = this.config.userAgent;
360
407
  }
408
+ if (!launchOpts.args && baseArgs.length > 0) {
409
+ launchOpts.args = baseArgs;
410
+ }
361
411
  await mgr.launch(launchOpts);
362
412
  this._contextStealthInstalled = false;
363
413
  this._uaOverrideApplied.clear();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poncho-ai/browser",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Browser automation for Poncho agents, powered by agent-browser",
5
5
  "repository": {
6
6
  "type": "git",
package/src/session.ts CHANGED
@@ -244,30 +244,94 @@ export class BrowserSession {
244
244
  }
245
245
  }
246
246
 
247
+ private get isRemote(): boolean {
248
+ return !!(this.config.provider || this.config.cdpUrl);
249
+ }
250
+
251
+ private get isServerless(): boolean {
252
+ return !!(
253
+ process.env.VERCEL ||
254
+ process.env.AWS_LAMBDA_FUNCTION_NAME ||
255
+ process.env.AWS_EXECUTION_ENV ||
256
+ process.env.SERVERLESS
257
+ );
258
+ }
259
+
260
+ /**
261
+ * Resolve executablePath and launch args for serverless platforms.
262
+ * When `@sparticuz/chromium` is installed, uses its executable and
263
+ * recommended args (--no-sandbox, --disable-gpu, etc.).
264
+ */
265
+ private async resolveServerlessChromium(): Promise<{
266
+ executablePath?: string;
267
+ args?: string[];
268
+ }> {
269
+ if (this.config.executablePath) return { executablePath: this.config.executablePath };
270
+ if (!this.isServerless) return {};
271
+ try {
272
+ const spec = ["@sparticuz", "chromium"].join("/");
273
+ const mod = await import(/* webpackIgnore: true */ spec);
274
+ const chromium = mod.default ?? mod;
275
+ const executablePath = await chromium.executablePath();
276
+ const args: string[] = Array.isArray(chromium.args) ? chromium.args : [];
277
+ console.log(`[poncho][browser] Auto-detected @sparticuz/chromium: ${executablePath} (${args.length} args)`);
278
+ return { executablePath, args };
279
+ } catch {
280
+ return {};
281
+ }
282
+ }
283
+
247
284
  private async launchFreshManager(): Promise<BrowserManagerInstance> {
248
285
  const Ctor = await getBrowserManagerCtor();
249
286
  const mgr = new Ctor();
250
287
 
251
288
  const viewport = this.config.viewport ?? { width: 1280, height: 720 };
252
- await mkdir(this.profileDir, { recursive: true });
289
+ const serverless = await this.resolveServerlessChromium();
253
290
 
254
291
  const launchOpts: Record<string, unknown> = {
255
292
  action: "launch",
256
293
  headless: this.config.headless ?? true,
257
294
  viewport: { width: viewport.width ?? 1280, height: viewport.height ?? 720 },
258
- executablePath: this.config.executablePath,
259
- profile: this.profileDir,
295
+ executablePath: serverless.executablePath,
260
296
  };
261
297
 
298
+ if (this.config.cdpUrl) {
299
+ launchOpts.cdpUrl = this.config.cdpUrl;
300
+ console.log(`[poncho][browser] Connecting via CDP: ${this.config.cdpUrl}`);
301
+ } else if (this.config.provider) {
302
+ launchOpts.provider = this.config.provider;
303
+ console.log(`[poncho][browser] Using cloud provider: ${this.config.provider}`);
304
+ } else {
305
+ const profileDir = this.isServerless && !this.config.profileDir
306
+ ? join(tmpdir(), "poncho-browser", this.sessionId)
307
+ : this.profileDir;
308
+ await mkdir(profileDir, { recursive: true });
309
+ launchOpts.profile = profileDir;
310
+ }
311
+
312
+ // Merge args: serverless chromium args (--no-sandbox etc.) + stealth args
313
+ const baseArgs: string[] = serverless.args ?? [];
314
+
262
315
  if (this.stealthEnabled) {
263
316
  const ua = this.stealthUserAgent!;
264
317
  launchOpts.userAgent = ua;
265
- launchOpts.args = buildStealthArgs(ua);
318
+ if (!this.isRemote) {
319
+ const stealthArgs = buildStealthArgs(ua);
320
+ const merged = [...baseArgs];
321
+ for (const arg of stealthArgs) {
322
+ if (!merged.includes(arg)) merged.push(arg);
323
+ }
324
+ launchOpts.args = merged;
325
+ }
266
326
  console.log("[poncho][browser] Launching with stealth mode enabled (UA: " + ua + ")");
267
327
  } else if (this.config.userAgent) {
268
328
  launchOpts.userAgent = this.config.userAgent;
269
329
  }
270
330
 
331
+ if (!launchOpts.args && baseArgs.length > 0) {
332
+ launchOpts.args = baseArgs;
333
+ }
334
+
271
335
  await mgr.launch(launchOpts as Parameters<BrowserManagerInstance["launch"]>[0]);
272
336
 
273
337
  // Reset stealth tracking for fresh browser
package/src/types.ts CHANGED
@@ -70,4 +70,11 @@ export interface BrowserConfig {
70
70
  * user-agent, and passes anti-automation Chrome flags. */
71
71
  stealth?: boolean;
72
72
  storagePersistence?: BrowserStoragePersistence;
73
+ /** Cloud browser provider. Requires the provider's API key env var to be set
74
+ * (e.g. `BROWSERBASE_API_KEY` + `BROWSERBASE_PROJECT_ID` for Browserbase).
75
+ * When set, the browser runs remotely instead of launching a local Chromium. */
76
+ provider?: "browserbase" | "browseruse" | "kernel";
77
+ /** Connect to an existing browser via Chrome DevTools Protocol URL or port.
78
+ * Mutually exclusive with `provider`. */
79
+ cdpUrl?: string;
73
80
  }