Skip to content

Commit 345ecc8

Browse files
Use mapping inputs for tool wrappers without mutation
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 929d2bd commit 345ecc8

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

hyperbrowser/tools/__init__.py

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,26 @@ def _prepare_extract_tool_params(params: Mapping[str, Any]) -> Dict[str, Any]:
3838
return normalized_params
3939

4040

41+
def _to_param_dict(params: Mapping[str, Any]) -> Dict[str, Any]:
42+
return dict(params)
43+
44+
4145
class WebsiteScrapeTool:
4246
openai_tool_definition = SCRAPE_TOOL_OPENAI
4347
anthropic_tool_definition = SCRAPE_TOOL_ANTHROPIC
4448

4549
@staticmethod
46-
def runnable(hb: Hyperbrowser, params: dict) -> str:
47-
resp = hb.scrape.start_and_wait(params=StartScrapeJobParams(**params))
50+
def runnable(hb: Hyperbrowser, params: Mapping[str, Any]) -> str:
51+
resp = hb.scrape.start_and_wait(
52+
params=StartScrapeJobParams(**_to_param_dict(params))
53+
)
4854
return resp.data.markdown if resp.data and resp.data.markdown else ""
4955

5056
@staticmethod
51-
async def async_runnable(hb: AsyncHyperbrowser, params: dict) -> str:
52-
resp = await hb.scrape.start_and_wait(params=StartScrapeJobParams(**params))
57+
async def async_runnable(hb: AsyncHyperbrowser, params: Mapping[str, Any]) -> str:
58+
resp = await hb.scrape.start_and_wait(
59+
params=StartScrapeJobParams(**_to_param_dict(params))
60+
)
5361
return resp.data.markdown if resp.data and resp.data.markdown else ""
5462

5563

@@ -58,13 +66,17 @@ class WebsiteScreenshotTool:
5866
anthropic_tool_definition = SCREENSHOT_TOOL_ANTHROPIC
5967

6068
@staticmethod
61-
def runnable(hb: Hyperbrowser, params: dict) -> str:
62-
resp = hb.scrape.start_and_wait(params=StartScrapeJobParams(**params))
69+
def runnable(hb: Hyperbrowser, params: Mapping[str, Any]) -> str:
70+
resp = hb.scrape.start_and_wait(
71+
params=StartScrapeJobParams(**_to_param_dict(params))
72+
)
6373
return resp.data.screenshot if resp.data and resp.data.screenshot else ""
6474

6575
@staticmethod
66-
async def async_runnable(hb: AsyncHyperbrowser, params: dict) -> str:
67-
resp = await hb.scrape.start_and_wait(params=StartScrapeJobParams(**params))
76+
async def async_runnable(hb: AsyncHyperbrowser, params: Mapping[str, Any]) -> str:
77+
resp = await hb.scrape.start_and_wait(
78+
params=StartScrapeJobParams(**_to_param_dict(params))
79+
)
6880
return resp.data.screenshot if resp.data and resp.data.screenshot else ""
6981

7082

@@ -73,8 +85,10 @@ class WebsiteCrawlTool:
7385
anthropic_tool_definition = CRAWL_TOOL_ANTHROPIC
7486

7587
@staticmethod
76-
def runnable(hb: Hyperbrowser, params: dict) -> str:
77-
resp = hb.crawl.start_and_wait(params=StartCrawlJobParams(**params))
88+
def runnable(hb: Hyperbrowser, params: Mapping[str, Any]) -> str:
89+
resp = hb.crawl.start_and_wait(
90+
params=StartCrawlJobParams(**_to_param_dict(params))
91+
)
7892
markdown = ""
7993
if resp.data:
8094
for page in resp.data:
@@ -85,8 +99,10 @@ def runnable(hb: Hyperbrowser, params: dict) -> str:
8599
return markdown
86100

87101
@staticmethod
88-
async def async_runnable(hb: AsyncHyperbrowser, params: dict) -> str:
89-
resp = await hb.crawl.start_and_wait(params=StartCrawlJobParams(**params))
102+
async def async_runnable(hb: AsyncHyperbrowser, params: Mapping[str, Any]) -> str:
103+
resp = await hb.crawl.start_and_wait(
104+
params=StartCrawlJobParams(**_to_param_dict(params))
105+
)
90106
markdown = ""
91107
if resp.data:
92108
for page in resp.data:
@@ -102,15 +118,15 @@ class WebsiteExtractTool:
102118
anthropic_tool_definition = EXTRACT_TOOL_ANTHROPIC
103119

104120
@staticmethod
105-
def runnable(hb: Hyperbrowser, params: dict) -> str:
121+
def runnable(hb: Hyperbrowser, params: Mapping[str, Any]) -> str:
106122
normalized_params = _prepare_extract_tool_params(params)
107123
resp = hb.extract.start_and_wait(
108124
params=StartExtractJobParams(**normalized_params)
109125
)
110126
return json.dumps(resp.data) if resp.data else ""
111127

112128
@staticmethod
113-
async def async_runnable(hb: AsyncHyperbrowser, params: dict) -> str:
129+
async def async_runnable(hb: AsyncHyperbrowser, params: Mapping[str, Any]) -> str:
114130
normalized_params = _prepare_extract_tool_params(params)
115131
resp = await hb.extract.start_and_wait(
116132
params=StartExtractJobParams(**normalized_params)
@@ -123,16 +139,16 @@ class BrowserUseTool:
123139
anthropic_tool_definition = BROWSER_USE_TOOL_ANTHROPIC
124140

125141
@staticmethod
126-
def runnable(hb: Hyperbrowser, params: dict) -> str:
142+
def runnable(hb: Hyperbrowser, params: Mapping[str, Any]) -> str:
127143
resp = hb.agents.browser_use.start_and_wait(
128-
params=StartBrowserUseTaskParams(**params)
144+
params=StartBrowserUseTaskParams(**_to_param_dict(params))
129145
)
130146
return resp.data.final_result if resp.data and resp.data.final_result else ""
131147

132148
@staticmethod
133-
async def async_runnable(hb: AsyncHyperbrowser, params: dict) -> str:
149+
async def async_runnable(hb: AsyncHyperbrowser, params: Mapping[str, Any]) -> str:
134150
resp = await hb.agents.browser_use.start_and_wait(
135-
params=StartBrowserUseTaskParams(**params)
151+
params=StartBrowserUseTaskParams(**_to_param_dict(params))
136152
)
137153
return resp.data.final_result if resp.data and resp.data.final_result else ""
138154

tests/test_url_building.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ def test_client_build_url_normalizes_leading_slash():
1313
client._build_url("/api/session")
1414
== "https://api.hyperbrowser.ai/api/session"
1515
)
16-
assert client._build_url("api/session") == "https://api.hyperbrowser.ai/api/session"
16+
assert (
17+
client._build_url("api/session")
18+
== "https://api.hyperbrowser.ai/api/session"
19+
)
1720
finally:
1821
client.close()
1922

0 commit comments

Comments
 (0)