@poncho-ai/browser 0.5.0 → 0.6.0

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.0 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 40.85 KB
11
+ ESM ⚡️ Build success in 76ms
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 1346ms
14
+ DTS dist/index.d.ts 13.55 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @poncho-ai/browser
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`76294e9`](https://github.com/cesr/poncho-ai/commit/76294e95035bf3abbb19c28871a33f82351c49ec) Thanks [@cesr](https://github.com/cesr)! - Support remote and serverless browser deployments.
8
+
9
+ **@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`.
10
+
11
+ **@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.
12
+
3
13
  ## 0.5.0
4
14
 
5
15
  ### 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,13 @@ 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 for local launches. When no explicit path is set
115
+ * and we're on a serverless platform, try `@sparticuz/chromium` automatically.
116
+ */
117
+ private resolveExecutablePath;
104
118
  private launchFreshManager;
105
119
  private ensureManager;
106
120
  private evictOldestTab;
package/dist/index.js CHANGED
@@ -338,22 +338,61 @@ 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 for local launches. When no explicit path is set
349
+ * and we're on a serverless platform, try `@sparticuz/chromium` automatically.
350
+ */
351
+ async resolveExecutablePath() {
352
+ if (this.config.executablePath) return this.config.executablePath;
353
+ if (!this.isServerless) return void 0;
354
+ try {
355
+ const spec = ["@sparticuz", "chromium"].join("/");
356
+ const mod = await import(
357
+ /* webpackIgnore: true */
358
+ spec
359
+ );
360
+ const chromium = mod.default ?? mod;
361
+ const path = await chromium.executablePath();
362
+ console.log(`[poncho][browser] Auto-detected @sparticuz/chromium: ${path}`);
363
+ return path;
364
+ } catch {
365
+ return void 0;
366
+ }
367
+ }
341
368
  async launchFreshManager() {
342
369
  const Ctor = await getBrowserManagerCtor();
343
370
  const mgr = new Ctor();
344
371
  const viewport = this.config.viewport ?? { width: 1280, height: 720 };
345
- await mkdir(this.profileDir, { recursive: true });
372
+ const executablePath = await this.resolveExecutablePath();
346
373
  const launchOpts = {
347
374
  action: "launch",
348
375
  headless: this.config.headless ?? true,
349
376
  viewport: { width: viewport.width ?? 1280, height: viewport.height ?? 720 },
350
- executablePath: this.config.executablePath,
351
- profile: this.profileDir
377
+ executablePath
352
378
  };
379
+ if (this.config.cdpUrl) {
380
+ launchOpts.cdpUrl = this.config.cdpUrl;
381
+ console.log(`[poncho][browser] Connecting via CDP: ${this.config.cdpUrl}`);
382
+ } else if (this.config.provider) {
383
+ launchOpts.provider = this.config.provider;
384
+ console.log(`[poncho][browser] Using cloud provider: ${this.config.provider}`);
385
+ } else {
386
+ const profileDir = this.isServerless && !this.config.profileDir ? join(tmpdir(), "poncho-browser", this.sessionId) : this.profileDir;
387
+ await mkdir(profileDir, { recursive: true });
388
+ launchOpts.profile = profileDir;
389
+ }
353
390
  if (this.stealthEnabled) {
354
391
  const ua = this.stealthUserAgent;
355
392
  launchOpts.userAgent = ua;
356
- launchOpts.args = buildStealthArgs(ua);
393
+ if (!this.isRemote) {
394
+ launchOpts.args = buildStealthArgs(ua);
395
+ }
357
396
  console.log("[poncho][browser] Launching with stealth mode enabled (UA: " + ua + ")");
358
397
  } else if (this.config.userAgent) {
359
398
  launchOpts.userAgent = this.config.userAgent;
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.0",
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,25 +244,74 @@ 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 for local launches. When no explicit path is set
262
+ * and we're on a serverless platform, try `@sparticuz/chromium` automatically.
263
+ */
264
+ private async resolveExecutablePath(): Promise<string | undefined> {
265
+ if (this.config.executablePath) return this.config.executablePath;
266
+ if (!this.isServerless) return undefined;
267
+ try {
268
+ // Dynamic require — @sparticuz/chromium is an optional peer dependency
269
+ // that the user installs in their agent project for serverless runtimes.
270
+ const spec = ["@sparticuz", "chromium"].join("/");
271
+ const mod = await import(/* webpackIgnore: true */ spec);
272
+ const chromium = mod.default ?? mod;
273
+ const path = await chromium.executablePath();
274
+ console.log(`[poncho][browser] Auto-detected @sparticuz/chromium: ${path}`);
275
+ return path;
276
+ } catch {
277
+ return undefined;
278
+ }
279
+ }
280
+
247
281
  private async launchFreshManager(): Promise<BrowserManagerInstance> {
248
282
  const Ctor = await getBrowserManagerCtor();
249
283
  const mgr = new Ctor();
250
284
 
251
285
  const viewport = this.config.viewport ?? { width: 1280, height: 720 };
252
- await mkdir(this.profileDir, { recursive: true });
286
+ const executablePath = await this.resolveExecutablePath();
253
287
 
254
288
  const launchOpts: Record<string, unknown> = {
255
289
  action: "launch",
256
290
  headless: this.config.headless ?? true,
257
291
  viewport: { width: viewport.width ?? 1280, height: viewport.height ?? 720 },
258
- executablePath: this.config.executablePath,
259
- profile: this.profileDir,
292
+ executablePath,
260
293
  };
261
294
 
295
+ if (this.config.cdpUrl) {
296
+ launchOpts.cdpUrl = this.config.cdpUrl;
297
+ console.log(`[poncho][browser] Connecting via CDP: ${this.config.cdpUrl}`);
298
+ } else if (this.config.provider) {
299
+ launchOpts.provider = this.config.provider;
300
+ console.log(`[poncho][browser] Using cloud provider: ${this.config.provider}`);
301
+ } else {
302
+ const profileDir = this.isServerless && !this.config.profileDir
303
+ ? join(tmpdir(), "poncho-browser", this.sessionId)
304
+ : this.profileDir;
305
+ await mkdir(profileDir, { recursive: true });
306
+ launchOpts.profile = profileDir;
307
+ }
308
+
262
309
  if (this.stealthEnabled) {
263
310
  const ua = this.stealthUserAgent!;
264
311
  launchOpts.userAgent = ua;
265
- launchOpts.args = buildStealthArgs(ua);
312
+ if (!this.isRemote) {
313
+ launchOpts.args = buildStealthArgs(ua);
314
+ }
266
315
  console.log("[poncho][browser] Launching with stealth mode enabled (UA: " + ua + ")");
267
316
  } else if (this.config.userAgent) {
268
317
  launchOpts.userAgent = this.config.userAgent;
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
  }