Skip to content

Commit 664a5b2

Browse files
Centralize shared agent operation metadata
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 5435d20 commit 664a5b2

16 files changed

Lines changed: 274 additions & 60 deletions

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ This runs lint, format checks, compile checks, tests, and package build.
7777
- Prefer deterministic unit tests over network-dependent tests.
7878
- Preserve architectural guardrails with focused tests. Current guard suites include:
7979
- `tests/test_agent_examples_coverage.py` (agent task example coverage enforcement),
80+
- `tests/test_agent_operation_metadata_usage.py` (shared agent operation-metadata usage enforcement),
8081
- `tests/test_agent_payload_helper_usage.py` (shared agent start-payload helper usage enforcement),
8182
- `tests/test_agent_stop_helper_usage.py` (shared agent stop-request helper usage enforcement),
8283
- `tests/test_agent_task_read_helper_usage.py` (shared agent task read-helper usage enforcement),
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from dataclasses import dataclass
2+
3+
4+
@dataclass(frozen=True)
5+
class AgentOperationMetadata:
6+
start_operation_name: str
7+
task_operation_name: str
8+
status_operation_name: str
9+
stop_operation_name: str
10+
start_error_message: str
11+
operation_name_prefix: str
12+
13+
14+
BROWSER_USE_OPERATION_METADATA = AgentOperationMetadata(
15+
start_operation_name="browser-use start",
16+
task_operation_name="browser-use task",
17+
status_operation_name="browser-use task status",
18+
stop_operation_name="browser-use task stop",
19+
start_error_message="Failed to start browser-use task job",
20+
operation_name_prefix="browser-use task job ",
21+
)
22+
23+
HYPER_AGENT_OPERATION_METADATA = AgentOperationMetadata(
24+
start_operation_name="hyper agent start",
25+
task_operation_name="hyper agent task",
26+
status_operation_name="hyper agent task status",
27+
stop_operation_name="hyper agent task stop",
28+
start_error_message="Failed to start HyperAgent task",
29+
operation_name_prefix="HyperAgent task ",
30+
)
31+
32+
GEMINI_COMPUTER_USE_OPERATION_METADATA = AgentOperationMetadata(
33+
start_operation_name="gemini computer use start",
34+
task_operation_name="gemini computer use task",
35+
status_operation_name="gemini computer use task status",
36+
stop_operation_name="gemini computer use task stop",
37+
start_error_message="Failed to start Gemini Computer Use task job",
38+
operation_name_prefix="Gemini Computer Use task job ",
39+
)
40+
41+
CLAUDE_COMPUTER_USE_OPERATION_METADATA = AgentOperationMetadata(
42+
start_operation_name="claude computer use start",
43+
task_operation_name="claude computer use task",
44+
status_operation_name="claude computer use task status",
45+
stop_operation_name="claude computer use task stop",
46+
start_error_message="Failed to start Claude Computer Use task job",
47+
operation_name_prefix="Claude Computer Use task job ",
48+
)
49+
50+
CUA_OPERATION_METADATA = AgentOperationMetadata(
51+
start_operation_name="cua start",
52+
task_operation_name="cua task",
53+
status_operation_name="cua task status",
54+
stop_operation_name="cua task stop",
55+
start_error_message="Failed to start CUA task job",
56+
operation_name_prefix="CUA task job ",
57+
)

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from ...agent_status_utils import is_agent_terminal_status
44
from ...browser_use_payload_utils import build_browser_use_start_payload
5+
from ...agent_operation_metadata import BROWSER_USE_OPERATION_METADATA
56
from ...agent_route_constants import BROWSER_USE_TASK_ROUTE_PREFIX
67
from ...agent_stop_utils import stop_agent_task_async
78
from ...agent_task_read_utils import get_agent_task_async, get_agent_task_status_async
@@ -24,6 +25,7 @@
2425

2526

2627
class BrowserUseManager:
28+
_OPERATION_METADATA = BROWSER_USE_OPERATION_METADATA
2729
_ROUTE_PREFIX = BROWSER_USE_TASK_ROUTE_PREFIX
2830

2931
def __init__(self, client):
@@ -40,7 +42,7 @@ async def start(
4042
return parse_response_model(
4143
response.data,
4244
model=StartBrowserUseTaskResponse,
43-
operation_name="browser-use start",
45+
operation_name=self._OPERATION_METADATA.start_operation_name,
4446
)
4547

4648
async def get(self, job_id: str) -> BrowserUseTaskResponse:
@@ -49,7 +51,7 @@ async def get(self, job_id: str) -> BrowserUseTaskResponse:
4951
route_prefix=self._ROUTE_PREFIX,
5052
job_id=job_id,
5153
model=BrowserUseTaskResponse,
52-
operation_name="browser-use task",
54+
operation_name=self._OPERATION_METADATA.task_operation_name,
5355
)
5456

5557
async def get_status(self, job_id: str) -> BrowserUseTaskStatusResponse:
@@ -58,15 +60,15 @@ async def get_status(self, job_id: str) -> BrowserUseTaskStatusResponse:
5860
route_prefix=self._ROUTE_PREFIX,
5961
job_id=job_id,
6062
model=BrowserUseTaskStatusResponse,
61-
operation_name="browser-use task status",
63+
operation_name=self._OPERATION_METADATA.status_operation_name,
6264
)
6365

6466
async def stop(self, job_id: str) -> BasicResponse:
6567
return await stop_agent_task_async(
6668
client=self._client,
6769
route_prefix=self._ROUTE_PREFIX,
6870
job_id=job_id,
69-
operation_name="browser-use task stop",
71+
operation_name=self._OPERATION_METADATA.stop_operation_name,
7072
)
7173

7274
async def start_and_wait(
@@ -79,8 +81,8 @@ async def start_and_wait(
7981
job_start_resp = await self.start(params)
8082
job_id, operation_name = build_started_job_context(
8183
started_job_id=job_start_resp.job_id,
82-
start_error_message="Failed to start browser-use task job",
83-
operation_name_prefix="browser-use task job ",
84+
start_error_message=self._OPERATION_METADATA.start_error_message,
85+
operation_name_prefix=self._OPERATION_METADATA.operation_name_prefix,
8486
)
8587

8688
return await wait_for_job_result_with_defaults_async(

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Optional
22

33
from ...agent_payload_utils import build_agent_start_payload
4+
from ...agent_operation_metadata import CLAUDE_COMPUTER_USE_OPERATION_METADATA
45
from ...agent_route_constants import CLAUDE_COMPUTER_USE_TASK_ROUTE_PREFIX
56
from ...agent_status_utils import is_agent_terminal_status
67
from ...agent_stop_utils import stop_agent_task_async
@@ -24,6 +25,7 @@
2425

2526

2627
class ClaudeComputerUseManager:
28+
_OPERATION_METADATA = CLAUDE_COMPUTER_USE_OPERATION_METADATA
2729
_ROUTE_PREFIX = CLAUDE_COMPUTER_USE_TASK_ROUTE_PREFIX
2830

2931
def __init__(self, client):
@@ -43,7 +45,7 @@ async def start(
4345
return parse_response_model(
4446
response.data,
4547
model=StartClaudeComputerUseTaskResponse,
46-
operation_name="claude computer use start",
48+
operation_name=self._OPERATION_METADATA.start_operation_name,
4749
)
4850

4951
async def get(self, job_id: str) -> ClaudeComputerUseTaskResponse:
@@ -52,7 +54,7 @@ async def get(self, job_id: str) -> ClaudeComputerUseTaskResponse:
5254
route_prefix=self._ROUTE_PREFIX,
5355
job_id=job_id,
5456
model=ClaudeComputerUseTaskResponse,
55-
operation_name="claude computer use task",
57+
operation_name=self._OPERATION_METADATA.task_operation_name,
5658
)
5759

5860
async def get_status(self, job_id: str) -> ClaudeComputerUseTaskStatusResponse:
@@ -61,15 +63,15 @@ async def get_status(self, job_id: str) -> ClaudeComputerUseTaskStatusResponse:
6163
route_prefix=self._ROUTE_PREFIX,
6264
job_id=job_id,
6365
model=ClaudeComputerUseTaskStatusResponse,
64-
operation_name="claude computer use task status",
66+
operation_name=self._OPERATION_METADATA.status_operation_name,
6567
)
6668

6769
async def stop(self, job_id: str) -> BasicResponse:
6870
return await stop_agent_task_async(
6971
client=self._client,
7072
route_prefix=self._ROUTE_PREFIX,
7173
job_id=job_id,
72-
operation_name="claude computer use task stop",
74+
operation_name=self._OPERATION_METADATA.stop_operation_name,
7375
)
7476

7577
async def start_and_wait(
@@ -82,8 +84,8 @@ async def start_and_wait(
8284
job_start_resp = await self.start(params)
8385
job_id, operation_name = build_started_job_context(
8486
started_job_id=job_start_resp.job_id,
85-
start_error_message="Failed to start Claude Computer Use task job",
86-
operation_name_prefix="Claude Computer Use task job ",
87+
start_error_message=self._OPERATION_METADATA.start_error_message,
88+
operation_name_prefix=self._OPERATION_METADATA.operation_name_prefix,
8789
)
8890

8991
return await wait_for_job_result_with_defaults_async(

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Optional
22

33
from ...agent_payload_utils import build_agent_start_payload
4+
from ...agent_operation_metadata import CUA_OPERATION_METADATA
45
from ...agent_route_constants import CUA_TASK_ROUTE_PREFIX
56
from ...agent_status_utils import is_agent_terminal_status
67
from ...agent_stop_utils import stop_agent_task_async
@@ -24,6 +25,7 @@
2425

2526

2627
class CuaManager:
28+
_OPERATION_METADATA = CUA_OPERATION_METADATA
2729
_ROUTE_PREFIX = CUA_TASK_ROUTE_PREFIX
2830

2931
def __init__(self, client):
@@ -41,7 +43,7 @@ async def start(self, params: StartCuaTaskParams) -> StartCuaTaskResponse:
4143
return parse_response_model(
4244
response.data,
4345
model=StartCuaTaskResponse,
44-
operation_name="cua start",
46+
operation_name=self._OPERATION_METADATA.start_operation_name,
4547
)
4648

4749
async def get(self, job_id: str) -> CuaTaskResponse:
@@ -50,7 +52,7 @@ async def get(self, job_id: str) -> CuaTaskResponse:
5052
route_prefix=self._ROUTE_PREFIX,
5153
job_id=job_id,
5254
model=CuaTaskResponse,
53-
operation_name="cua task",
55+
operation_name=self._OPERATION_METADATA.task_operation_name,
5456
)
5557

5658
async def get_status(self, job_id: str) -> CuaTaskStatusResponse:
@@ -59,15 +61,15 @@ async def get_status(self, job_id: str) -> CuaTaskStatusResponse:
5961
route_prefix=self._ROUTE_PREFIX,
6062
job_id=job_id,
6163
model=CuaTaskStatusResponse,
62-
operation_name="cua task status",
64+
operation_name=self._OPERATION_METADATA.status_operation_name,
6365
)
6466

6567
async def stop(self, job_id: str) -> BasicResponse:
6668
return await stop_agent_task_async(
6769
client=self._client,
6870
route_prefix=self._ROUTE_PREFIX,
6971
job_id=job_id,
70-
operation_name="cua task stop",
72+
operation_name=self._OPERATION_METADATA.stop_operation_name,
7173
)
7274

7375
async def start_and_wait(
@@ -80,8 +82,8 @@ async def start_and_wait(
8082
job_start_resp = await self.start(params)
8183
job_id, operation_name = build_started_job_context(
8284
started_job_id=job_start_resp.job_id,
83-
start_error_message="Failed to start CUA task job",
84-
operation_name_prefix="CUA task job ",
85+
start_error_message=self._OPERATION_METADATA.start_error_message,
86+
operation_name_prefix=self._OPERATION_METADATA.operation_name_prefix,
8587
)
8688

8789
return await wait_for_job_result_with_defaults_async(

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Optional
22

33
from ...agent_payload_utils import build_agent_start_payload
4+
from ...agent_operation_metadata import GEMINI_COMPUTER_USE_OPERATION_METADATA
45
from ...agent_route_constants import GEMINI_COMPUTER_USE_TASK_ROUTE_PREFIX
56
from ...agent_status_utils import is_agent_terminal_status
67
from ...agent_stop_utils import stop_agent_task_async
@@ -24,6 +25,7 @@
2425

2526

2627
class GeminiComputerUseManager:
28+
_OPERATION_METADATA = GEMINI_COMPUTER_USE_OPERATION_METADATA
2729
_ROUTE_PREFIX = GEMINI_COMPUTER_USE_TASK_ROUTE_PREFIX
2830

2931
def __init__(self, client):
@@ -43,7 +45,7 @@ async def start(
4345
return parse_response_model(
4446
response.data,
4547
model=StartGeminiComputerUseTaskResponse,
46-
operation_name="gemini computer use start",
48+
operation_name=self._OPERATION_METADATA.start_operation_name,
4749
)
4850

4951
async def get(self, job_id: str) -> GeminiComputerUseTaskResponse:
@@ -52,7 +54,7 @@ async def get(self, job_id: str) -> GeminiComputerUseTaskResponse:
5254
route_prefix=self._ROUTE_PREFIX,
5355
job_id=job_id,
5456
model=GeminiComputerUseTaskResponse,
55-
operation_name="gemini computer use task",
57+
operation_name=self._OPERATION_METADATA.task_operation_name,
5658
)
5759

5860
async def get_status(self, job_id: str) -> GeminiComputerUseTaskStatusResponse:
@@ -61,15 +63,15 @@ async def get_status(self, job_id: str) -> GeminiComputerUseTaskStatusResponse:
6163
route_prefix=self._ROUTE_PREFIX,
6264
job_id=job_id,
6365
model=GeminiComputerUseTaskStatusResponse,
64-
operation_name="gemini computer use task status",
66+
operation_name=self._OPERATION_METADATA.status_operation_name,
6567
)
6668

6769
async def stop(self, job_id: str) -> BasicResponse:
6870
return await stop_agent_task_async(
6971
client=self._client,
7072
route_prefix=self._ROUTE_PREFIX,
7173
job_id=job_id,
72-
operation_name="gemini computer use task stop",
74+
operation_name=self._OPERATION_METADATA.stop_operation_name,
7375
)
7476

7577
async def start_and_wait(
@@ -82,8 +84,8 @@ async def start_and_wait(
8284
job_start_resp = await self.start(params)
8385
job_id, operation_name = build_started_job_context(
8486
started_job_id=job_start_resp.job_id,
85-
start_error_message="Failed to start Gemini Computer Use task job",
86-
operation_name_prefix="Gemini Computer Use task job ",
87+
start_error_message=self._OPERATION_METADATA.start_error_message,
88+
operation_name_prefix=self._OPERATION_METADATA.operation_name_prefix,
8789
)
8890

8991
return await wait_for_job_result_with_defaults_async(

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Optional
22

33
from ...agent_payload_utils import build_agent_start_payload
4+
from ...agent_operation_metadata import HYPER_AGENT_OPERATION_METADATA
45
from ...agent_route_constants import HYPER_AGENT_TASK_ROUTE_PREFIX
56
from ...agent_status_utils import is_agent_terminal_status
67
from ...agent_stop_utils import stop_agent_task_async
@@ -24,6 +25,7 @@
2425

2526

2627
class HyperAgentManager:
28+
_OPERATION_METADATA = HYPER_AGENT_OPERATION_METADATA
2729
_ROUTE_PREFIX = HYPER_AGENT_TASK_ROUTE_PREFIX
2830

2931
def __init__(self, client):
@@ -43,7 +45,7 @@ async def start(
4345
return parse_response_model(
4446
response.data,
4547
model=StartHyperAgentTaskResponse,
46-
operation_name="hyper agent start",
48+
operation_name=self._OPERATION_METADATA.start_operation_name,
4749
)
4850

4951
async def get(self, job_id: str) -> HyperAgentTaskResponse:
@@ -52,7 +54,7 @@ async def get(self, job_id: str) -> HyperAgentTaskResponse:
5254
route_prefix=self._ROUTE_PREFIX,
5355
job_id=job_id,
5456
model=HyperAgentTaskResponse,
55-
operation_name="hyper agent task",
57+
operation_name=self._OPERATION_METADATA.task_operation_name,
5658
)
5759

5860
async def get_status(self, job_id: str) -> HyperAgentTaskStatusResponse:
@@ -61,15 +63,15 @@ async def get_status(self, job_id: str) -> HyperAgentTaskStatusResponse:
6163
route_prefix=self._ROUTE_PREFIX,
6264
job_id=job_id,
6365
model=HyperAgentTaskStatusResponse,
64-
operation_name="hyper agent task status",
66+
operation_name=self._OPERATION_METADATA.status_operation_name,
6567
)
6668

6769
async def stop(self, job_id: str) -> BasicResponse:
6870
return await stop_agent_task_async(
6971
client=self._client,
7072
route_prefix=self._ROUTE_PREFIX,
7173
job_id=job_id,
72-
operation_name="hyper agent task stop",
74+
operation_name=self._OPERATION_METADATA.stop_operation_name,
7375
)
7476

7577
async def start_and_wait(
@@ -82,8 +84,8 @@ async def start_and_wait(
8284
job_start_resp = await self.start(params)
8385
job_id, operation_name = build_started_job_context(
8486
started_job_id=job_start_resp.job_id,
85-
start_error_message="Failed to start HyperAgent task",
86-
operation_name_prefix="HyperAgent task ",
87+
start_error_message=self._OPERATION_METADATA.start_error_message,
88+
operation_name_prefix=self._OPERATION_METADATA.operation_name_prefix,
8789
)
8890

8991
return await wait_for_job_result_with_defaults_async(

0 commit comments

Comments
 (0)