diff --git a/hyperbrowser/models/__init__.py b/hyperbrowser/models/__init__.py index 43d483d5..49d8f29e 100644 --- a/hyperbrowser/models/__init__.py +++ b/hyperbrowser/models/__init__.py @@ -168,7 +168,9 @@ HyperAgentLlm, BrowserUseLlm, ClaudeComputerUseLlm, + ClaudeComputerUseReasoningEffort, CuaLlm, + CuaReasoningEffort, GrokComputerUseLlm, GrokReasoningEffort, MetaComputerUseLlm, @@ -428,7 +430,9 @@ "HyperAgentLlm", "BrowserUseLlm", "ClaudeComputerUseLlm", + "ClaudeComputerUseReasoningEffort", "CuaLlm", + "CuaReasoningEffort", "Country", "DownloadsStatus", "FetchScreenshotFormat", diff --git a/hyperbrowser/models/agents/claude_computer_use.py b/hyperbrowser/models/agents/claude_computer_use.py index 316ee8ad..5679f87d 100644 --- a/hyperbrowser/models/agents/claude_computer_use.py +++ b/hyperbrowser/models/agents/claude_computer_use.py @@ -5,7 +5,7 @@ from pydantic import BaseModel, ConfigDict, Field from ..session import CreateSessionParams -from ..consts import ClaudeComputerUseLlm +from ..consts import ClaudeComputerUseLlm, ClaudeComputerUseReasoningEffort ClaudeComputerUseTaskStatus = Literal[ "pending", "running", "completed", "failed", "stopped" @@ -35,6 +35,9 @@ class StartClaudeComputerUseTaskParams(BaseModel): task: str llm: Optional[ClaudeComputerUseLlm] = Field(default=None, serialization_alias="llm") + reasoning_effort: Optional[ClaudeComputerUseReasoningEffort] = Field( + default=None, serialization_alias="reasoningEffort" + ) session_id: Optional[str] = Field(default=None, serialization_alias="sessionId") max_failures: Optional[int] = Field(default=None, serialization_alias="maxFailures") max_steps: Optional[int] = Field(default=None, serialization_alias="maxSteps") diff --git a/hyperbrowser/models/agents/cua.py b/hyperbrowser/models/agents/cua.py index f99f4eb6..154649c0 100644 --- a/hyperbrowser/models/agents/cua.py +++ b/hyperbrowser/models/agents/cua.py @@ -4,7 +4,7 @@ from pydantic import BaseModel, ConfigDict, Field -from ..consts import CuaLlm +from ..consts import CuaLlm, CuaReasoningEffort from ..session import CreateSessionParams CuaTaskStatus = Literal["pending", "running", "completed", "failed", "stopped"] @@ -45,6 +45,9 @@ class StartCuaTaskParams(BaseModel): task: str llm: Optional[CuaLlm] = Field(default=None, serialization_alias="llm") + reasoning_effort: Optional[CuaReasoningEffort] = Field( + default=None, serialization_alias="reasoningEffort" + ) session_id: Optional[str] = Field(default=None, serialization_alias="sessionId") max_failures: Optional[int] = Field(default=None, serialization_alias="maxFailures") max_steps: Optional[int] = Field(default=None, serialization_alias="maxSteps") diff --git a/hyperbrowser/models/consts.py b/hyperbrowser/models/consts.py index 2335afef..41a4d79a 100644 --- a/hyperbrowser/models/consts.py +++ b/hyperbrowser/models/consts.py @@ -81,6 +81,13 @@ "claude-sonnet-4-20250514", "claude-3-7-sonnet-20250219", ] +ClaudeComputerUseReasoningEffort = Literal[ + "low", + "medium", + "high", + "xhigh", + "max", +] CuaLlm = Literal[ "computer-use-preview", "gpt-6-astra", @@ -91,6 +98,14 @@ "gpt-5.4", "gpt-5.4-mini", ] +CuaReasoningEffort = Literal[ + "none", + "low", + "medium", + "high", + "xhigh", + "max", +] GeminiComputerUseLlm = Literal[ "gemini-3.8-flash", "gemini-3.7-flash", diff --git a/hyperbrowser/types/agents.py b/hyperbrowser/types/agents.py index 63ca110f..dc8b4b8a 100644 --- a/hyperbrowser/types/agents.py +++ b/hyperbrowser/types/agents.py @@ -6,7 +6,9 @@ BrowserUseLlm, BrowserUseVersion, ClaudeComputerUseLlm, + ClaudeComputerUseReasoningEffort, CuaLlm, + CuaReasoningEffort, GeminiComputerUseLlm, GrokComputerUseLlm, GrokReasoningEffort, @@ -66,6 +68,7 @@ class StartClaudeComputerUseTaskParams(TypedDict, total=False): task: Required[str] llm: Optional[ClaudeComputerUseLlm] + reasoning_effort: Optional[ClaudeComputerUseReasoningEffort] session_id: Optional[str] max_failures: Optional[int] max_steps: Optional[int] @@ -158,6 +161,7 @@ class StartCuaTaskParams(TypedDict, total=False): task: Required[str] llm: Optional[CuaLlm] + reasoning_effort: Optional[CuaReasoningEffort] session_id: Optional[str] max_failures: Optional[int] max_steps: Optional[int] diff --git a/pyproject.toml b/pyproject.toml index cd6441c9..359d738d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "hyperbrowser" -version = "1.4.2" +version = "1.4.3" description = "Python SDK for hyperbrowser" authors = ["Nikhil Shahi "] license = "MIT" diff --git a/tests/test_request_compat.py b/tests/test_request_compat.py index db19c13d..4fe23f5b 100644 --- a/tests/test_request_compat.py +++ b/tests/test_request_compat.py @@ -8,11 +8,13 @@ normalize_pydantic_schema, ) from hyperbrowser.models import ( + ClaudeComputerUseApiKeys, CuaBaseUrls, CreateSandboxParams, CreateSessionParams, MetaComputerUseApiKeys, StartBrowserUseTaskParams, + StartClaudeComputerUseTaskParams, StartCuaTaskParams, StartMetaComputerUseTaskParams, ) @@ -83,6 +85,8 @@ def test_mapping_uses_existing_cross_field_validation(): def test_cua_custom_base_url_serializes_for_mapping_and_legacy_model(): mapping = { "task": "Complete the task", + "llm": "gpt-5.6-terra", + "reasoning_effort": "high", "use_custom_api_keys": True, "api_keys": {"openai": "openai-key"}, "base_urls": { @@ -91,6 +95,8 @@ def test_cua_custom_base_url_serializes_for_mapping_and_legacy_model(): } legacy = StartCuaTaskParams( task="Complete the task", + llm="gpt-5.6-terra", + reasoning_effort="high", use_custom_api_keys=True, api_keys={"openai": "openai-key"}, base_urls=CuaBaseUrls(openai="https://example.openai.azure.com/openai/v1/"), @@ -102,6 +108,8 @@ def test_cua_custom_base_url_serializes_for_mapping_and_legacy_model(): ) assert dump_request(mapping, StartCuaTaskParams) == { "task": "Complete the task", + "llm": "gpt-5.6-terra", + "reasoningEffort": "high", "useCustomApiKeys": True, "apiKeys": {"openai": "openai-key"}, "baseUrls": { @@ -110,6 +118,35 @@ def test_cua_custom_base_url_serializes_for_mapping_and_legacy_model(): } +def test_claude_computer_use_serializes_reasoning_effort_for_mapping_and_legacy_model(): + mapping = { + "task": "Complete the task", + "llm": "claude-opus-5", + "reasoning_effort": "xhigh", + "use_custom_api_keys": True, + "api_keys": {"anthropic": "anthropic-key"}, + } + legacy = StartClaudeComputerUseTaskParams( + task="Complete the task", + llm="claude-opus-5", + reasoning_effort="xhigh", + use_custom_api_keys=True, + api_keys=ClaudeComputerUseApiKeys(anthropic="anthropic-key"), + ) + + assert dump_request(mapping, StartClaudeComputerUseTaskParams) == dump_request( + legacy, + StartClaudeComputerUseTaskParams, + ) + assert dump_request(mapping, StartClaudeComputerUseTaskParams) == { + "task": "Complete the task", + "llm": "claude-opus-5", + "reasoningEffort": "xhigh", + "useCustomApiKeys": True, + "apiKeys": {"anthropic": "anthropic-key"}, + } + + def test_meta_computer_use_serializes_for_mapping_and_legacy_model(): mapping = { "task": "Complete the task", diff --git a/tests/typecheck/valid_requests.py b/tests/typecheck/valid_requests.py index 7e3587e2..657ec48c 100644 --- a/tests/typecheck/valid_requests.py +++ b/tests/typecheck/valid_requests.py @@ -99,6 +99,8 @@ def valid_sync_requests(client: Hyperbrowser) -> None: client.agents.cua.start( { "task": "Complete the task", + "llm": "gpt-5.6-terra", + "reasoning_effort": "high", "use_custom_api_keys": True, "api_keys": {"openai": "openai-key"}, "base_urls": { @@ -106,6 +108,13 @@ def valid_sync_requests(client: Hyperbrowser) -> None: }, } ) + client.agents.claude_computer_use.start( + { + "task": "Complete the task", + "llm": "claude-opus-5", + "reasoning_effort": "xhigh", + } + ) client.agents.meta_computer_use.start( { "task": "Complete the task", @@ -235,6 +244,8 @@ async def valid_async_requests(client: AsyncHyperbrowser) -> None: await client.agents.cua.start( { "task": "Complete the task", + "llm": "gpt-5.4", + "reasoning_effort": "none", "use_custom_api_keys": True, "api_keys": {"openai": "openai-key"}, "base_urls": { @@ -242,6 +253,13 @@ async def valid_async_requests(client: AsyncHyperbrowser) -> None: }, } ) + await client.agents.claude_computer_use.start( + { + "task": "Complete the task", + "llm": "claude-sonnet-4-6", + "reasoning_effort": "max", + } + ) await client.agents.meta_computer_use.start( { "task": "Complete the task",