Skip to content

Commit 2085578

Browse files
NikhilShahicursoragentnikhil
authored
Add Meta Computer Use agent (#123)
* feat: add Meta Computer Use agent Expose sync and async Muse Spark 1.1 computer-use managers with TypedDict and legacy request models. Co-authored-by: nikhil <nikhil@metlo.com> * feat: add muse-spark-1.2/1.3 and max reasoning for Meta Computer Use Keep TypedDict and legacy Pydantic request paths aligned with the current API. Co-authored-by: nikhil <nikhil@metlo.com> * Keep Meta Computer Use reasoning.summary on parsed steps. Meta history uses effort/summary, not CUA's generate_summary field. Co-authored-by: nikhil <nikhil@metlo.com> * Parse live Meta Computer Use envelope fields on get responses. Keep createdAt, finishedAt, liveDomain, and jobParams instead of dropping them from the production task payload. Co-authored-by: nikhil <nikhil@metlo.com> * Drop Meta envelope fields that other agents omit. Keep the task response aligned with Grok/CUA: no createdAt, finishedAt, liveDomain, or jobParams. Co-authored-by: nikhil <nikhil@metlo.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: nikhil <nikhil@metlo.com>
1 parent 0f315fb commit 2085578

13 files changed

Lines changed: 549 additions & 1 deletion

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ client.crawl # Website crawling jobs
4747
client.extract # Data extraction jobs
4848
client.web # Web fetch/search operations
4949
client.web.batch_fetch # Batch web fetch operations
50-
client.agents # AI agent integrations (browser_use, cua, claude_computer_use, hyper_agent, gemini_computer_use)
50+
client.agents # AI agent integrations (browser_use, cua, claude_computer_use, hyper_agent, gemini_computer_use, grok_computer_use, meta_computer_use)
5151
client.profiles # Browser profile management
5252
client.extensions # Browser extension management
5353
client.team # Team/credit info

hyperbrowser/client/managers/async_manager/agents/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from .hyper_agent import HyperAgentManager
55
from .gemini_computer_use import GeminiComputerUseManager
66
from .grok_computer_use import GrokComputerUseManager
7+
from .meta_computer_use import MetaComputerUseManager
78

89

910
class Agents:
@@ -14,3 +15,4 @@ def __init__(self, client):
1415
self.hyper_agent = HyperAgentManager(client)
1516
self.gemini_computer_use = GeminiComputerUseManager(client)
1617
self.grok_computer_use = GrokComputerUseManager(client)
18+
self.meta_computer_use = MetaComputerUseManager(client)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import asyncio
2+
from typing import Union
3+
4+
from hyperbrowser.client._request import dump_request
5+
from hyperbrowser.exceptions import HyperbrowserError
6+
from hyperbrowser.types import (
7+
StartMetaComputerUseTaskParams as StartMetaComputerUseTaskParamsDict,
8+
)
9+
10+
from .....models import (
11+
POLLING_ATTEMPTS,
12+
BasicResponse,
13+
MetaComputerUseTaskResponse,
14+
MetaComputerUseTaskStatusResponse,
15+
StartMetaComputerUseTaskParams,
16+
StartMetaComputerUseTaskResponse,
17+
)
18+
19+
20+
class MetaComputerUseManager:
21+
def __init__(self, client):
22+
self._client = client
23+
24+
async def start(
25+
self,
26+
params: Union[
27+
StartMetaComputerUseTaskParamsDict,
28+
StartMetaComputerUseTaskParams,
29+
],
30+
) -> StartMetaComputerUseTaskResponse:
31+
response = await self._client.transport.post(
32+
self._client._build_url("/task/meta-computer-use"),
33+
data=dump_request(params, StartMetaComputerUseTaskParams),
34+
)
35+
return StartMetaComputerUseTaskResponse(**response.data)
36+
37+
async def get(self, job_id: str) -> MetaComputerUseTaskResponse:
38+
response = await self._client.transport.get(
39+
self._client._build_url(f"/task/meta-computer-use/{job_id}")
40+
)
41+
return MetaComputerUseTaskResponse(**response.data)
42+
43+
async def get_status(self, job_id: str) -> MetaComputerUseTaskStatusResponse:
44+
response = await self._client.transport.get(
45+
self._client._build_url(f"/task/meta-computer-use/{job_id}/status")
46+
)
47+
return MetaComputerUseTaskStatusResponse(**response.data)
48+
49+
async def stop(self, job_id: str) -> BasicResponse:
50+
response = await self._client.transport.put(
51+
self._client._build_url(f"/task/meta-computer-use/{job_id}/stop")
52+
)
53+
return BasicResponse(**response.data)
54+
55+
async def start_and_wait(
56+
self,
57+
params: Union[
58+
StartMetaComputerUseTaskParamsDict,
59+
StartMetaComputerUseTaskParams,
60+
],
61+
) -> MetaComputerUseTaskResponse:
62+
job_start_resp = await self.start(params)
63+
job_id = job_start_resp.job_id
64+
if not job_id:
65+
raise HyperbrowserError("Failed to start Meta Computer Use task job")
66+
67+
failures = 0
68+
while True:
69+
try:
70+
job_response = await self.get_status(job_id)
71+
if (
72+
job_response.status == "completed"
73+
or job_response.status == "failed"
74+
or job_response.status == "stopped"
75+
):
76+
return await self.get(job_id)
77+
failures = 0
78+
except Exception as e:
79+
failures += 1
80+
if failures >= POLLING_ATTEMPTS:
81+
raise HyperbrowserError(
82+
f"Failed to poll Meta Computer Use task job {job_id} after {POLLING_ATTEMPTS} attempts: {e}"
83+
)
84+
await asyncio.sleep(2)

hyperbrowser/client/managers/sync_manager/agents/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from .hyper_agent import HyperAgentManager
55
from .gemini_computer_use import GeminiComputerUseManager
66
from .grok_computer_use import GrokComputerUseManager
7+
from .meta_computer_use import MetaComputerUseManager
78

89

910
class Agents:
@@ -14,3 +15,4 @@ def __init__(self, client):
1415
self.hyper_agent = HyperAgentManager(client)
1516
self.gemini_computer_use = GeminiComputerUseManager(client)
1617
self.grok_computer_use = GrokComputerUseManager(client)
18+
self.meta_computer_use = MetaComputerUseManager(client)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import time
2+
from typing import Union
3+
4+
from hyperbrowser.client._request import dump_request
5+
from hyperbrowser.exceptions import HyperbrowserError
6+
from hyperbrowser.types import (
7+
StartMetaComputerUseTaskParams as StartMetaComputerUseTaskParamsDict,
8+
)
9+
10+
from .....models import (
11+
POLLING_ATTEMPTS,
12+
BasicResponse,
13+
MetaComputerUseTaskResponse,
14+
MetaComputerUseTaskStatusResponse,
15+
StartMetaComputerUseTaskParams,
16+
StartMetaComputerUseTaskResponse,
17+
)
18+
19+
20+
class MetaComputerUseManager:
21+
def __init__(self, client):
22+
self._client = client
23+
24+
def start(
25+
self,
26+
params: Union[
27+
StartMetaComputerUseTaskParamsDict,
28+
StartMetaComputerUseTaskParams,
29+
],
30+
) -> StartMetaComputerUseTaskResponse:
31+
response = self._client.transport.post(
32+
self._client._build_url("/task/meta-computer-use"),
33+
data=dump_request(params, StartMetaComputerUseTaskParams),
34+
)
35+
return StartMetaComputerUseTaskResponse(**response.data)
36+
37+
def get(self, job_id: str) -> MetaComputerUseTaskResponse:
38+
response = self._client.transport.get(
39+
self._client._build_url(f"/task/meta-computer-use/{job_id}")
40+
)
41+
return MetaComputerUseTaskResponse(**response.data)
42+
43+
def get_status(self, job_id: str) -> MetaComputerUseTaskStatusResponse:
44+
response = self._client.transport.get(
45+
self._client._build_url(f"/task/meta-computer-use/{job_id}/status")
46+
)
47+
return MetaComputerUseTaskStatusResponse(**response.data)
48+
49+
def stop(self, job_id: str) -> BasicResponse:
50+
response = self._client.transport.put(
51+
self._client._build_url(f"/task/meta-computer-use/{job_id}/stop")
52+
)
53+
return BasicResponse(**response.data)
54+
55+
def start_and_wait(
56+
self,
57+
params: Union[
58+
StartMetaComputerUseTaskParamsDict,
59+
StartMetaComputerUseTaskParams,
60+
],
61+
) -> MetaComputerUseTaskResponse:
62+
job_start_resp = self.start(params)
63+
job_id = job_start_resp.job_id
64+
if not job_id:
65+
raise HyperbrowserError("Failed to start Meta Computer Use task job")
66+
67+
failures = 0
68+
while True:
69+
try:
70+
job_response = self.get_status(job_id)
71+
if (
72+
job_response.status == "completed"
73+
or job_response.status == "failed"
74+
or job_response.status == "stopped"
75+
):
76+
return self.get(job_id)
77+
failures = 0
78+
except Exception as e:
79+
failures += 1
80+
if failures >= POLLING_ATTEMPTS:
81+
raise HyperbrowserError(
82+
f"Failed to poll Meta Computer Use task job {job_id} after {POLLING_ATTEMPTS} attempts: {e}"
83+
)
84+
time.sleep(2)

hyperbrowser/models/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@
127127
StartGrokComputerUseTaskResponse,
128128
GrokComputerUseApiKeys,
129129
)
130+
from .agents.meta_computer_use import (
131+
MetaComputerUseTaskStatus,
132+
MetaComputerUseStepReasoning,
133+
MetaComputerUseStepResponse,
134+
MetaComputerUseTaskData,
135+
MetaComputerUseTaskResponse,
136+
MetaComputerUseTaskStatusResponse,
137+
StartMetaComputerUseTaskParams,
138+
StartMetaComputerUseTaskResponse,
139+
MetaComputerUseApiKeys,
140+
)
130141
from .agents.cua import (
131142
CuaTaskData,
132143
CuaTaskResponse,
@@ -160,6 +171,8 @@
160171
CuaLlm,
161172
GrokComputerUseLlm,
162173
GrokReasoningEffort,
174+
MetaComputerUseLlm,
175+
MetaReasoningEffort,
163176
Country,
164177
DownloadsStatus,
165178
FetchScreenshotFormat,
@@ -496,6 +509,14 @@
496509
"GrokComputerUseTaskStatusResponse",
497510
"StartGrokComputerUseTaskParams",
498511
"StartGrokComputerUseTaskResponse",
512+
"MetaComputerUseTaskStatus",
513+
"MetaComputerUseStepReasoning",
514+
"MetaComputerUseStepResponse",
515+
"MetaComputerUseTaskData",
516+
"MetaComputerUseTaskResponse",
517+
"MetaComputerUseTaskStatusResponse",
518+
"StartMetaComputerUseTaskParams",
519+
"StartMetaComputerUseTaskResponse",
499520
"CuaTaskStatus",
500521
"CuaTaskData",
501522
"CuaTaskResponse",
@@ -506,11 +527,14 @@
506527
"ClaudeComputerUseApiKeys",
507528
"GeminiComputerUseApiKeys",
508529
"GrokComputerUseApiKeys",
530+
"MetaComputerUseApiKeys",
509531
"CuaApiKeys",
510532
"CuaBaseUrls",
511533
"HyperAgentApiKeys",
512534
"GrokComputerUseLlm",
513535
"GrokReasoningEffort",
536+
"MetaComputerUseLlm",
537+
"MetaReasoningEffort",
514538
"HyperAgentOutputV110",
515539
"HyperAgentStepV110",
516540
# crawl

0 commit comments

Comments
 (0)