Skip to content

Commit 228b014

Browse files
committed
feat: add per-request browser config (proxy, profile, extensions, timeout)
Add optional `browser` field to CUA payload for per-request browser session configuration. Supports proxy_id, profile (id/name/save_changes), extensions, and timeout_seconds. Viewport and stealth remain deploy-time defaults since CUA providers depend on consistent viewport dimensions. Made-with: Cursor
1 parent 9cca4a8 commit 228b014

6 files changed

Lines changed: 85 additions & 6 deletions

File tree

pkg/templates/python/cua/.env.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@ CUA_PROVIDER=anthropic
1212
ANTHROPIC_API_KEY=your_anthropic_api_key_here
1313
OPENAI_API_KEY=your_openai_api_key_here
1414
GOOGLE_API_KEY=your_google_api_key_here
15+
16+
# Browser config (proxy, profile, extensions, timeout) is set per-request
17+
# via the payload "browser" field, not here. Example:
18+
# kernel invoke python-cua cua-task --payload '{
19+
# "query": "...",
20+
# "browser": {
21+
# "proxy_id": "proxy_abc123",
22+
# "profile": { "name": "my-profile", "save_changes": true },
23+
# "extensions": [{ "name": "my-extension" }],
24+
# "timeout_seconds": 600
25+
# }
26+
# }'

pkg/templates/python/cua/main.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,30 @@
2525
app = kernel.App("python-cua")
2626

2727

28+
class BrowserProfile(TypedDict, total=False):
29+
id: str
30+
name: str
31+
save_changes: bool
32+
33+
34+
class BrowserExtension(TypedDict, total=False):
35+
id: str
36+
name: str
37+
38+
39+
class BrowserConfig(TypedDict, total=False):
40+
proxy_id: str
41+
profile: BrowserProfile
42+
extensions: list[BrowserExtension]
43+
timeout_seconds: int
44+
45+
2846
class CuaInput(TypedDict, total=False):
2947
query: str
3048
provider: Literal["anthropic", "openai", "gemini"]
3149
model: str
3250
record_replay: bool
51+
browser: BrowserConfig
3352

3453

3554
class CuaOutput(TypedDict, total=False):
@@ -64,12 +83,17 @@ async def cua_task(ctx: kernel.KernelContext, payload: CuaInput | None = None) -
6483
if requested:
6584
providers = [requested] + [p for p in providers if p is not requested]
6685

86+
browser_cfg = payload.get("browser") or {}
6787
session = KernelBrowserSession(
6888
kernel_client,
6989
SessionOptions(
7090
invocation_id=ctx.invocation_id,
7191
stealth=True,
7292
record_replay=payload.get("record_replay", False),
93+
proxy_id=browser_cfg.get("proxy_id"),
94+
profile=browser_cfg.get("profile"),
95+
extensions=browser_cfg.get("extensions"),
96+
timeout_seconds=browser_cfg.get("timeout_seconds", 300),
7397
),
7498
)
7599

pkg/templates/python/cua/session.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ class SessionOptions:
1919
replay_grace_period: float = 5.0
2020
viewport_width: int = 1280
2121
viewport_height: int = 800
22+
proxy_id: str | None = None
23+
profile: dict | None = None
24+
extensions: list[dict] | None = None
2225

2326

2427
@dataclass
@@ -68,15 +71,25 @@ def info(self) -> SessionInfo:
6871
)
6972

7073
async def start(self) -> SessionInfo:
71-
browser = await asyncio.to_thread(
72-
self.kernel.browsers.create,
73-
invocation_id=self.opts.invocation_id,
74-
stealth=self.opts.stealth,
75-
timeout_seconds=self.opts.timeout_seconds,
76-
viewport={
74+
create_kwargs: dict = {
75+
"invocation_id": self.opts.invocation_id,
76+
"stealth": self.opts.stealth,
77+
"timeout_seconds": self.opts.timeout_seconds,
78+
"viewport": {
7779
"width": self.opts.viewport_width,
7880
"height": self.opts.viewport_height,
7981
},
82+
}
83+
if self.opts.proxy_id:
84+
create_kwargs["proxy_id"] = self.opts.proxy_id
85+
if self.opts.profile:
86+
create_kwargs["profile"] = self.opts.profile
87+
if self.opts.extensions:
88+
create_kwargs["extensions"] = self.opts.extensions
89+
90+
browser = await asyncio.to_thread(
91+
self.kernel.browsers.create,
92+
**create_kwargs,
8093
)
8194

8295
self._session_id = browser.session_id

pkg/templates/typescript/cua/.env.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,15 @@ CUA_PROVIDER=anthropic
1212
ANTHROPIC_API_KEY=your_anthropic_api_key_here
1313
OPENAI_API_KEY=your_openai_api_key_here
1414
GOOGLE_API_KEY=your_google_api_key_here
15+
16+
# Browser config (proxy, profile, extensions, timeout) is set per-request
17+
# via the payload "browser" field, not here. Example:
18+
# kernel invoke ts-cua cua-task --payload '{
19+
# "query": "...",
20+
# "browser": {
21+
# "proxy_id": "proxy_abc123",
22+
# "profile": { "name": "my-profile", "save_changes": true },
23+
# "extensions": [{ "name": "my-extension" }],
24+
# "timeout_seconds": 600
25+
# }
26+
# }'

pkg/templates/typescript/cua/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,19 @@ import { resolveProviders, runWithFallback, type ProviderName } from './provider
1717
const kernel = new Kernel();
1818
const app = kernel.app('ts-cua');
1919

20+
interface BrowserConfig {
21+
proxy_id?: string;
22+
profile?: { id?: string; name?: string; save_changes?: boolean };
23+
extensions?: Array<{ id?: string; name?: string }>;
24+
timeout_seconds?: number;
25+
}
26+
2027
interface CuaInput {
2128
query: string;
2229
provider?: ProviderName;
2330
model?: string;
2431
record_replay?: boolean;
32+
browser?: BrowserConfig;
2533
}
2634

2735
interface CuaOutput {
@@ -62,6 +70,10 @@ app.action<CuaInput, CuaOutput>(
6270
invocationId: ctx.invocation_id,
6371
stealth: true,
6472
recordReplay: payload.record_replay ?? false,
73+
...(payload.browser?.proxy_id ? { proxyId: payload.browser.proxy_id } : {}),
74+
...(payload.browser?.profile ? { profile: payload.browser.profile } : {}),
75+
...(payload.browser?.extensions ? { extensions: payload.browser.extensions } : {}),
76+
...(payload.browser?.timeout_seconds ? { timeoutSeconds: payload.browser.timeout_seconds } : {}),
6577
});
6678

6779
await session.start();

pkg/templates/typescript/cua/session.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export interface SessionOptions {
1414
replayGracePeriod?: number;
1515
viewportWidth?: number;
1616
viewportHeight?: number;
17+
proxyId?: string;
18+
profile?: { id?: string; name?: string; save_changes?: boolean };
19+
extensions?: Array<{ id?: string; name?: string }>;
1720
}
1821

1922
export interface SessionInfo {
@@ -75,6 +78,9 @@ export class KernelBrowserSession {
7578
stealth: this.opts.stealth,
7679
timeout_seconds: this.opts.timeoutSeconds,
7780
viewport: { width: this.opts.viewportWidth, height: this.opts.viewportHeight },
81+
...(this.opts.proxyId ? { proxy_id: this.opts.proxyId } : {}),
82+
...(this.opts.profile ? { profile: this.opts.profile } : {}),
83+
...(this.opts.extensions?.length ? { extensions: this.opts.extensions } : {}),
7884
});
7985

8086
this._sessionId = browser.session_id;

0 commit comments

Comments
 (0)