diff --git a/src/agent/index.ts b/src/agent/index.ts index edf93d3..8e52181 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -45,6 +45,7 @@ export class HyperAgent { : LocalBrowserProvider; private browserProviderType: T; private actions: Array = [...DEFAULT_ACTIONS]; + private clientType: "desktop" | "mobile"; public browser: Browser | null = null; public context: BrowserContext | null = null; @@ -76,6 +77,7 @@ export class HyperAgent { this.llm = params.llm; } this.browserProviderType = (params.browserProvider ?? "Local") as T; + this.clientType = params.clientType ?? "desktop"; this.browserProvider = ( this.browserProviderType === "Hyperbrowser" @@ -100,9 +102,13 @@ export class HyperAgent { public async initBrowser(): Promise { if (!this.browser) { this.browser = await this.browserProvider.start(); - this.context = await this.browser.newContext({ - viewport: null, - }); + this.context = await this.browserProvider.getContext(this.clientType); + + if (!this.context) { + this.context = await this.browser.newContext({ + viewport: null, + }); + } // Inject script to track event listeners await this.context.addInitScript(() => { diff --git a/src/browser-providers/hyperbrowser.ts b/src/browser-providers/hyperbrowser.ts index 78084d7..63bcd14 100644 --- a/src/browser-providers/hyperbrowser.ts +++ b/src/browser-providers/hyperbrowser.ts @@ -1,4 +1,10 @@ -import { chromium, Browser, ConnectOverCDPOptions } from "playwright"; +import { + chromium, + Browser, + ConnectOverCDPOptions, + BrowserContext, + devices, +} from "playwright"; import { Hyperbrowser } from "@hyperbrowser/sdk"; import { CreateSessionParams, @@ -62,6 +68,25 @@ export class HyperbrowserProvider extends BrowserProvider { } } + public async getContext( + device: string = "desktop" + ): Promise { + if (!this.browser) return null; + + if (device === "mobile") { + const iPhone = devices["iPhone 12"]; + return await this.browser.newContext({ + userAgent: iPhone.userAgent, + viewport: { + width: iPhone.viewport.width + 50, + height: iPhone.viewport.height + 50, + }, + }); + } + + return await this.browser.newContext(); + } + public getSession() { if (!this.session) { return null; diff --git a/src/browser-providers/local.ts b/src/browser-providers/local.ts index 976c772..3b50db5 100644 --- a/src/browser-providers/local.ts +++ b/src/browser-providers/local.ts @@ -1,13 +1,21 @@ -import { chromium, Browser, LaunchOptions } from "playwright"; +import { + chromium, + Browser, + LaunchOptions, + devices, + BrowserContext, +} from "playwright"; import BrowserProvider from "@/types/browser-providers/types"; export class LocalBrowserProvider extends BrowserProvider { options: Omit, "channel"> | undefined; session: Browser | undefined; + constructor(options?: Omit, "channel">) { super(); this.options = options; } + async start(): Promise { const launchArgs = this.options?.args ?? []; const browser = await chromium.launch({ @@ -19,13 +27,34 @@ export class LocalBrowserProvider extends BrowserProvider { this.session = browser; return this.session; } + async close(): Promise { return await this.session?.close(); } + public getSession() { if (!this.session) { return null; } return this.session; } + + public async getContext( + device: string = "desktop" + ): Promise { + if (!this.session) return null; + + if (device === "mobile") { + const iPhone = devices["iPhone 12"]; + return await this.session.newContext({ + userAgent: iPhone.userAgent, + viewport: { + width: iPhone.viewport.width + 50, + height: iPhone.viewport.height + 50, + }, + }); + } + + return await this.session.newContext(); + } } diff --git a/src/types/browser-providers/types.ts b/src/types/browser-providers/types.ts index f01e62a..3e33e4e 100644 --- a/src/types/browser-providers/types.ts +++ b/src/types/browser-providers/types.ts @@ -1,10 +1,11 @@ -import { Browser } from "playwright"; +import { Browser, BrowserContext } from "playwright"; abstract class BrowserProvider { abstract session: unknown; abstract start(): Promise; abstract close(): Promise; - abstract getSession(): T|null; + abstract getSession(): T | null; + abstract getContext(device?: string): Promise; } export default BrowserProvider; diff --git a/src/types/config.ts b/src/types/config.ts index 8ea80bf..f690130 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -63,7 +63,7 @@ export interface HyperAgentConfig { debug?: boolean; llm?: BaseChatModel; - + clientType?: "mobile" | "desktop"; hyperbrowserConfig?: Omit< NonNullable[0]>, "debug"