# -*- coding: utf-8 -*-
# pylint: disable=too-many-public-methods
from typing import Optional
from urllib.parse import urlparse, urlunparse
from ...constant import IMAGE_TAG
from ...registry import SandboxRegistry
from ...enums import SandboxType
from ...box.sandbox import Sandbox
def http_to_ws(url, use_localhost=True):
parsed = urlparse(url)
ws_scheme = "wss" if parsed.scheme == "https" else "ws"
hostname = parsed.hostname
if use_localhost and hostname == "127.0.0.1":
hostname = "localhost"
if parsed.port:
new_netloc = f"{hostname}:{parsed.port}"
else:
new_netloc = hostname
ws_url = urlunparse(parsed._replace(scheme=ws_scheme, netloc=new_netloc))
return ws_url
[docs]
@SandboxRegistry.register(
f"agentscope/runtime-sandbox-browser:{IMAGE_TAG}",
sandbox_type=SandboxType.BROWSER,
security_level="medium",
timeout=60,
description="Browser sandbox",
)
class BrowserSandbox(Sandbox):
[docs]
def __init__(
self,
sandbox_id: Optional[str] = None,
timeout: int = 3000,
base_url: Optional[str] = None,
bearer_token: Optional[str] = None,
):
super().__init__(
sandbox_id,
timeout,
base_url,
bearer_token,
SandboxType.BROWSER,
)
@property
def browser_ws(self):
if self.base_url is None:
# Local mode
return self.get_info()["front_browser_ws"]
return http_to_ws(f"{self.base_url}/browser/{self.sandbox_id}/cast")
[docs]
def browser_close(self):
return self.call_tool("browser_close", {})
[docs]
def browser_resize(self, width: int, height: int):
return self.call_tool(
"browser_resize",
{"width": width, "height": height},
)
[docs]
def browser_console_messages(self):
return self.call_tool("browser_console_messages", {})
[docs]
def browser_handle_dialog(self, accept: bool, prompt_text: str = ""):
return self.call_tool(
"browser_handle_dialog",
{"accept": accept, "promptText": prompt_text},
)
[docs]
def browser_file_upload(self, paths: list):
return self.call_tool("browser_file_upload", {"paths": paths})
[docs]
def browser_press_key(self, key: str):
return self.call_tool("browser_press_key", {"key": key})
[docs]
def browser_navigate(self, url: str):
return self.call_tool("browser_navigate", {"url": url})
[docs]
def browser_navigate_back(self):
return self.call_tool("browser_navigate_back", {})
[docs]
def browser_navigate_forward(self):
return self.call_tool("browser_navigate_forward", {})
[docs]
def browser_network_requests(self):
return self.call_tool("browser_network_requests", {})
[docs]
def browser_pdf_save(self, filename: str = ""):
return self.call_tool("browser_pdf_save", {"filename": filename})
[docs]
def browser_take_screenshot(
self,
raw: bool = False,
filename: str = "",
element: str = "",
ref: str = "",
):
return self.call_tool(
"browser_take_screenshot",
{
"raw": raw,
"filename": filename,
"element": element,
"ref": ref,
},
)
[docs]
def browser_snapshot(self):
return self.call_tool("browser_snapshot", {})
[docs]
def browser_click(self, element: str, ref: str):
return self.call_tool(
"browser_click",
{"element": element, "ref": ref},
)
[docs]
def browser_drag(
self,
start_element: str,
start_ref: str,
end_element: str,
end_ref: str,
):
return self.call_tool(
"browser_drag",
{
"startElement": start_element,
"startRef": start_ref,
"endElement": end_element,
"endRef": end_ref,
},
)
[docs]
def browser_hover(self, element: str, ref: str):
return self.call_tool(
"browser_hover",
{"element": element, "ref": ref},
)
[docs]
def browser_type(
self,
element: str,
ref: str,
text: str,
submit: bool = False,
slowly: bool = False,
):
return self.call_tool(
"browser_type",
{
"element": element,
"ref": ref,
"text": text,
"submit": submit,
"slowly": slowly,
},
)
[docs]
def browser_select_option(self, element: str, ref: str, values: list):
return self.call_tool(
"browser_select_option",
{
"element": element,
"ref": ref,
"values": values,
},
)
[docs]
def browser_tab_list(self):
return self.call_tool("browser_tab_list", {})
[docs]
def browser_tab_new(self, url: str = ""):
return self.call_tool("browser_tab_new", {"url": url})
[docs]
def browser_tab_select(self, index: int):
return self.call_tool("browser_tab_select", {"index": index})
[docs]
def browser_tab_close(self, index: int = None):
return self.call_tool("browser_tab_close", {"index": index})
[docs]
def browser_wait_for(
self,
time: float = None,
text: str = None,
text_gone: str = None,
):
return self.call_tool(
"browser_wait_for",
{
"time": time,
"text": text,
"textGone": text_gone,
},
)