Skip to content

Commit f56a9c2

Browse files
authored
Add cua to mode (#1432)
# why Move cua to mode enum for consistency across modes # what changed deprecated cua: true, in favor of mode: "cua" # test plan tested locally <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Move CUA config from a boolean flag to the mode enum for consistency across agent modes. Use mode: "cua"; cua: true is deprecated and now emits a runtime warning. - **Refactors** - Added "cua" to AgentToolMode and updated public types/tests. - Deprecated AgentConfig.cua with a deprecation warning. - Centralized CUA detection (mode: "cua" or legacy cua: true) in validation, cache, and agent creation. - Improved agent logging to include mode and unified CUA feature checks. - **Migration** - Replace AgentConfig cua: true with mode: "cua". <sup>Written for commit 1f1b807. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. -->
1 parent e0e22e0 commit f56a9c2

File tree

6 files changed

+43
-12
lines changed

6 files changed

+43
-12
lines changed

.changeset/rich-donuts-shake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@browserbasehq/stagehand": patch
3+
---
4+
5+
Deprecate cua: true in favor of mode: "cua"

packages/core/lib/v3/agent/utils/validateExperimentalFeatures.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ export function validateExperimentalFeatures(
3434
): void {
3535
const { isExperimental, agentConfig, executeOptions, isStreaming } = options;
3636

37+
// Check if CUA mode is enabled (via mode: "cua" or deprecated cua: true)
38+
const isCuaMode = agentConfig?.mode === "cua" || agentConfig?.cua === true;
39+
3740
// CUA-specific validation: certain features are not available at all
38-
if (agentConfig?.cua) {
41+
if (isCuaMode) {
3942
const unsupportedFeatures: string[] = [];
4043

4144
if (agentConfig?.stream) {
@@ -73,12 +76,12 @@ export function validateExperimentalFeatures(
7376
}
7477

7578
// Check streaming mode (either explicit or derived from config) - only for non-CUA
76-
if (!agentConfig?.cua && (isStreaming || agentConfig?.stream)) {
79+
if (!isCuaMode && (isStreaming || agentConfig?.stream)) {
7780
features.push("streaming");
7881
}
7982

8083
// Check execute options features - only for non-CUA
81-
if (executeOptions && !agentConfig?.cua) {
84+
if (executeOptions && !isCuaMode) {
8285
if (executeOptions.callbacks) {
8386
features.push("callbacks");
8487
}

packages/core/lib/v3/cache/AgentCache.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,17 @@ export class AgentCache {
109109
const serializedExecutionModel = this.serializeAgentModelForCache(
110110
agentOptions?.executionModel,
111111
);
112+
113+
const isCuaMode =
114+
agentOptions?.mode === "cua" || agentOptions?.cua === true;
115+
112116
return JSON.stringify({
113117
v3Model: this.getBaseModelName(),
114118
systemPrompt: this.getSystemPrompt() ?? "",
115119
agent: {
116-
cua: agentOptions?.cua ?? false,
120+
cua: isCuaMode,
117121
model: serializedModel ?? null,
118-
executionModel: agentOptions?.cua ? null : serializedExecutionModel,
122+
executionModel: isCuaMode ? null : serializedExecutionModel,
119123
systemPrompt: agentOptions?.systemPrompt ?? null,
120124
toolKeys,
121125
integrations: integrationSignatures,

packages/core/lib/v3/types/public/agent.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,9 @@ export type AgentModelConfig<TModelName extends string = string> = {
401401
* Agent tool mode determines which set of tools are available to the agent.
402402
* - 'dom': Uses DOM-based tools (act, fillForm) - better for structured page interactions
403403
* - 'hybrid': Uses coordinate-based tools (click, type, dragAndDrop, etc.) - better for visual/screenshot-based interactions
404+
* - 'cua': Uses Computer Use Agent (CUA) providers like Anthropic Claude or Google Gemini for screenshot-based automation
404405
*/
405-
export type AgentToolMode = "dom" | "hybrid";
406+
export type AgentToolMode = "dom" | "hybrid" | "cua";
406407

407408
export type AgentConfig = {
408409
/**
@@ -418,7 +419,8 @@ export type AgentConfig = {
418419
*/
419420
tools?: ToolSet;
420421
/**
421-
* Indicates CUA is disabled for this configuration
422+
* @deprecated Use `mode: "cua"` instead. This option will be removed in a future version.
423+
* Enables Computer Use Agent (CUA) mode.
422424
*/
423425
cua?: boolean;
424426
/**
@@ -442,7 +444,7 @@ export type AgentConfig = {
442444
* - 'dom' (default): Uses DOM-based tools (act, fillForm) for structured interactions
443445
* - 'hybrid': Uses coordinate-based tools (click, type, dragAndDrop, clickAndHold, fillFormVision)
444446
* for visual/screenshot-based interactions
445-
* @experimental hybrid mode requires `experimental: true` in Stagehand constructor
447+
* - 'cua': Uses Computer Use Agent (CUA) providers for screenshot-based automation
446448
*/
447449
mode?: AgentToolMode;
448450
};

packages/core/lib/v3/v3.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,12 +1665,29 @@ export class V3 {
16651665
| AgentStreamExecuteOptions,
16661666
) => Promise<AgentResult | AgentStreamResult>;
16671667
} {
1668+
// Determine if CUA mode is enabled (via mode: "cua" or deprecated cua: true)
1669+
const isCuaMode = options?.mode === "cua" || options?.cua === true;
1670+
1671+
// Emit deprecation warning for cua: true
1672+
if (options?.cua === true) {
1673+
this.logger({
1674+
category: "agent",
1675+
message:
1676+
'[DEPRECATED] The "cua: true" option is deprecated. Use "mode: \'cua\'" instead. This option will be removed in a future version.',
1677+
level: 0,
1678+
});
1679+
console.warn(
1680+
'[Stagehand] DEPRECATED: The "cua: true" option is deprecated. Use "mode: \'cua\'" instead.',
1681+
);
1682+
}
1683+
16681684
this.logger({
16691685
category: "agent",
16701686
message: `Creating v3 agent instance with options: ${JSON.stringify(options)}`,
16711687
level: 1,
16721688
auxiliary: {
1673-
cua: { value: options?.cua ? "true" : "false", type: "boolean" },
1689+
cua: { value: isCuaMode ? "true" : "false", type: "boolean" },
1690+
mode: { value: options?.mode ?? "dom", type: "string" },
16741691
model: options?.model
16751692
? typeof options?.model === "string"
16761693
? { value: options.model, type: "string" }
@@ -1687,8 +1704,8 @@ export class V3 {
16871704
},
16881705
});
16891706

1690-
// If CUA is enabled, use the computer-use agent path
1691-
if (options?.cua) {
1707+
// If CUA mode is enabled (via mode: "cua" or deprecated cua: true), use the computer-use agent path
1708+
if (isCuaMode) {
16921709
// Validate agent config at creation time (includes CUA+streaming conflict check)
16931710
validateExperimentalFeatures({
16941711
isExperimental: this.experimental,

packages/core/tests/public-api/public-types.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ describe("Stagehand public API types", () => {
273273
});
274274

275275
describe("AgentToolMode", () => {
276-
type ExpectedAgentToolMode = "dom" | "hybrid";
276+
type ExpectedAgentToolMode = "dom" | "hybrid" | "cua";
277277

278278
it("matches expected type shape", () => {
279279
expectTypeOf<Stagehand.AgentToolMode>().toEqualTypeOf<ExpectedAgentToolMode>();

0 commit comments

Comments
 (0)