anchorbrowser 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anchorbrowser/__init__.py +100 -0
- anchorbrowser/_base_client.py +1995 -0
- anchorbrowser/_client.py +440 -0
- anchorbrowser/_compat.py +219 -0
- anchorbrowser/_constants.py +14 -0
- anchorbrowser/_exceptions.py +108 -0
- anchorbrowser/_files.py +123 -0
- anchorbrowser/_models.py +829 -0
- anchorbrowser/_qs.py +150 -0
- anchorbrowser/_resource.py +43 -0
- anchorbrowser/_response.py +832 -0
- anchorbrowser/_streaming.py +333 -0
- anchorbrowser/_types.py +219 -0
- anchorbrowser/_utils/__init__.py +57 -0
- anchorbrowser/_utils/_logs.py +25 -0
- anchorbrowser/_utils/_proxy.py +65 -0
- anchorbrowser/_utils/_reflection.py +42 -0
- anchorbrowser/_utils/_resources_proxy.py +24 -0
- anchorbrowser/_utils/_streams.py +12 -0
- anchorbrowser/_utils/_sync.py +86 -0
- anchorbrowser/_utils/_transform.py +447 -0
- anchorbrowser/_utils/_typing.py +151 -0
- anchorbrowser/_utils/_utils.py +422 -0
- anchorbrowser/_version.py +4 -0
- anchorbrowser/lib/.keep +4 -0
- anchorbrowser/lib/agent.py +69 -0
- anchorbrowser/lib/browser.py +186 -0
- anchorbrowser/py.typed +0 -0
- anchorbrowser/resources/__init__.py +61 -0
- anchorbrowser/resources/agent.py +305 -0
- anchorbrowser/resources/browser.py +152 -0
- anchorbrowser/resources/extensions.py +412 -0
- anchorbrowser/resources/profiles.py +553 -0
- anchorbrowser/resources/sessions/__init__.py +89 -0
- anchorbrowser/resources/sessions/all.py +192 -0
- anchorbrowser/resources/sessions/clipboard.py +252 -0
- anchorbrowser/resources/sessions/keyboard.py +298 -0
- anchorbrowser/resources/sessions/mouse.py +651 -0
- anchorbrowser/resources/sessions/recordings/__init__.py +33 -0
- anchorbrowser/resources/sessions/recordings/primary.py +176 -0
- anchorbrowser/resources/sessions/recordings/recordings.py +357 -0
- anchorbrowser/resources/sessions/sessions.py +1122 -0
- anchorbrowser/resources/tools.py +529 -0
- anchorbrowser/types/__init__.py +32 -0
- anchorbrowser/types/extension_delete_response.py +12 -0
- anchorbrowser/types/extension_list_response.py +31 -0
- anchorbrowser/types/extension_manifest.py +28 -0
- anchorbrowser/types/extension_retrieve_response.py +27 -0
- anchorbrowser/types/extension_upload_params.py +17 -0
- anchorbrowser/types/extension_upload_response.py +31 -0
- anchorbrowser/types/profile_create_params.py +31 -0
- anchorbrowser/types/profile_list_response.py +43 -0
- anchorbrowser/types/profile_retrieve_response.py +36 -0
- anchorbrowser/types/profile_update_params.py +27 -0
- anchorbrowser/types/session_copy_response.py +12 -0
- anchorbrowser/types/session_create_params.py +196 -0
- anchorbrowser/types/session_create_response.py +22 -0
- anchorbrowser/types/session_drag_and_drop_params.py +26 -0
- anchorbrowser/types/session_drag_and_drop_response.py +11 -0
- anchorbrowser/types/session_goto_params.py +12 -0
- anchorbrowser/types/session_goto_response.py +11 -0
- anchorbrowser/types/session_paste_params.py +12 -0
- anchorbrowser/types/session_paste_response.py +11 -0
- anchorbrowser/types/session_retrieve_downloads_response.py +51 -0
- anchorbrowser/types/session_scroll_params.py +26 -0
- anchorbrowser/types/session_scroll_response.py +11 -0
- anchorbrowser/types/sessions/__init__.py +25 -0
- anchorbrowser/types/sessions/all_status_response.py +30 -0
- anchorbrowser/types/sessions/clipboard_get_response.py +16 -0
- anchorbrowser/types/sessions/clipboard_set_params.py +12 -0
- anchorbrowser/types/sessions/clipboard_set_response.py +11 -0
- anchorbrowser/types/sessions/keyboard_shortcut_params.py +18 -0
- anchorbrowser/types/sessions/keyboard_shortcut_response.py +11 -0
- anchorbrowser/types/sessions/keyboard_type_params.py +15 -0
- anchorbrowser/types/sessions/keyboard_type_response.py +11 -0
- anchorbrowser/types/sessions/mouse_click_params.py +18 -0
- anchorbrowser/types/sessions/mouse_click_response.py +11 -0
- anchorbrowser/types/sessions/mouse_double_click_params.py +18 -0
- anchorbrowser/types/sessions/mouse_double_click_response.py +11 -0
- anchorbrowser/types/sessions/mouse_down_params.py +18 -0
- anchorbrowser/types/sessions/mouse_down_response.py +11 -0
- anchorbrowser/types/sessions/mouse_move_params.py +15 -0
- anchorbrowser/types/sessions/mouse_move_response.py +11 -0
- anchorbrowser/types/sessions/mouse_up_params.py +18 -0
- anchorbrowser/types/sessions/mouse_up_response.py +11 -0
- anchorbrowser/types/sessions/recording_list_response.py +46 -0
- anchorbrowser/types/sessions/recording_pause_response.py +12 -0
- anchorbrowser/types/sessions/recording_resume_response.py +12 -0
- anchorbrowser/types/sessions/recordings/__init__.py +3 -0
- anchorbrowser/types/shared/__init__.py +3 -0
- anchorbrowser/types/shared/success_response.py +15 -0
- anchorbrowser/types/tool_fetch_webpage_params.py +26 -0
- anchorbrowser/types/tool_fetch_webpage_response.py +7 -0
- anchorbrowser/types/tool_perform_web_task_params.py +30 -0
- anchorbrowser/types/tool_perform_web_task_response.py +16 -0
- anchorbrowser/types/tool_screenshot_webpage_params.py +48 -0
- anchorbrowser-0.1.0.dist-info/METADATA +449 -0
- anchorbrowser-0.1.0.dist-info/RECORD +100 -0
- anchorbrowser-0.1.0.dist-info/WHEEL +4 -0
- anchorbrowser-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, Callable, Optional, TypedDict
|
|
2
|
+
from contextlib import contextmanager, asynccontextmanager, _GeneratorContextManager, _AsyncGeneratorContextManager
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
from playwright.sync_api import Page, Worker, Browser, BrowserContext
|
|
6
|
+
from playwright.async_api import (
|
|
7
|
+
Page as AsyncPage,
|
|
8
|
+
Worker as AsyncWorker,
|
|
9
|
+
Browser as AsyncBrowser,
|
|
10
|
+
BrowserContext as AsyncBrowserContext,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from collections import Generator, AsyncGenerator
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@contextmanager
|
|
18
|
+
def get_playwright_chromium_from_cdp_url(
|
|
19
|
+
api_base_url: str, session_id: str, api_key: str
|
|
20
|
+
) -> "Generator[Browser, Any, None]":
|
|
21
|
+
from playwright.sync_api import sync_playwright
|
|
22
|
+
|
|
23
|
+
browser = None
|
|
24
|
+
playwright = sync_playwright().start()
|
|
25
|
+
try:
|
|
26
|
+
browser = playwright.chromium.connect_over_cdp(get_cdp_url(api_base_url, session_id, api_key))
|
|
27
|
+
yield browser
|
|
28
|
+
finally:
|
|
29
|
+
if browser:
|
|
30
|
+
browser.close()
|
|
31
|
+
playwright.stop()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@asynccontextmanager
|
|
35
|
+
async def get_async_playwright_chromium_from_cdp_url(
|
|
36
|
+
api_base_url: str, session_id: str, api_key: str
|
|
37
|
+
) -> "AsyncGenerator[AsyncBrowser, None]":
|
|
38
|
+
from playwright.async_api import async_playwright
|
|
39
|
+
|
|
40
|
+
browser = None
|
|
41
|
+
playwright = await async_playwright().start()
|
|
42
|
+
try:
|
|
43
|
+
browser = await playwright.chromium.connect_over_cdp(get_cdp_url(api_base_url, session_id, api_key))
|
|
44
|
+
yield browser
|
|
45
|
+
finally:
|
|
46
|
+
if browser:
|
|
47
|
+
await browser.close()
|
|
48
|
+
await playwright.stop()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_cdp_url(api_base_url: str, session_id: str, api_key: str) -> str:
|
|
52
|
+
return f"{api_base_url.replace('https://', 'wss://').replace('api.', 'connect.')}?apiKey={api_key}&sessionId={session_id}"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_agent_ws_url(api_base_url: str, session_id: str) -> str:
|
|
56
|
+
return f"{api_base_url.replace('https://', 'wss://')}/ws?sessionId={session_id}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_ai_service_worker(browser_context: "BrowserContext") -> Optional["Worker"]:
|
|
60
|
+
return next(
|
|
61
|
+
(
|
|
62
|
+
sw
|
|
63
|
+
for sw in browser_context.service_workers
|
|
64
|
+
if "chrome-extension://bppehibnhionalpjigdjdilknbljaeai/background.js" in sw.url
|
|
65
|
+
),
|
|
66
|
+
None,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
async def get_ai_service_worker_async(browser_context: "AsyncBrowserContext") -> Optional["AsyncWorker"]:
|
|
71
|
+
return next(
|
|
72
|
+
(
|
|
73
|
+
sw
|
|
74
|
+
for sw in browser_context.service_workers
|
|
75
|
+
if "chrome-extension://bppehibnhionalpjigdjdilknbljaeai/background.js" in sw.url
|
|
76
|
+
),
|
|
77
|
+
None,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class BrowserSetup(BaseModel):
|
|
82
|
+
session_id: str
|
|
83
|
+
base_url: str
|
|
84
|
+
api_key: str
|
|
85
|
+
_browser: Optional[Browser] = None
|
|
86
|
+
_async_browser: Optional[AsyncBrowser] = None
|
|
87
|
+
_context_manager: Optional[_GeneratorContextManager[Browser]] = None
|
|
88
|
+
_async_context_manager: Optional[_AsyncGeneratorContextManager[AsyncBrowser]] = None
|
|
89
|
+
|
|
90
|
+
async def __aenter__(self) -> "BrowserSetup":
|
|
91
|
+
self._async_context_manager = get_async_playwright_chromium_from_cdp_url(
|
|
92
|
+
self.base_url,
|
|
93
|
+
self.session_id,
|
|
94
|
+
self.api_key,
|
|
95
|
+
)
|
|
96
|
+
self._async_browser = await self._async_context_manager.__aenter__()
|
|
97
|
+
return self
|
|
98
|
+
|
|
99
|
+
def __enter__(self) -> "BrowserSetup":
|
|
100
|
+
self._context_manager = get_playwright_chromium_from_cdp_url(
|
|
101
|
+
self.base_url,
|
|
102
|
+
self.session_id,
|
|
103
|
+
self.api_key,
|
|
104
|
+
)
|
|
105
|
+
self._browser = self._context_manager.__enter__()
|
|
106
|
+
return self
|
|
107
|
+
|
|
108
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Optional[bool]:
|
|
109
|
+
if self._context_manager:
|
|
110
|
+
return self._context_manager.__exit__(exc_type, exc_val, exc_tb)
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Optional[bool]:
|
|
114
|
+
if self._async_context_manager:
|
|
115
|
+
return await self._async_context_manager.__aexit__(exc_type, exc_val, exc_tb)
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def browser_generator(self) -> _GeneratorContextManager[Browser]:
|
|
120
|
+
return get_playwright_chromium_from_cdp_url(
|
|
121
|
+
self.base_url,
|
|
122
|
+
self.session_id,
|
|
123
|
+
self.api_key,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def async_browser_generator(self) -> _AsyncGeneratorContextManager[AsyncBrowser]:
|
|
128
|
+
return get_async_playwright_chromium_from_cdp_url(
|
|
129
|
+
self.base_url,
|
|
130
|
+
self.session_id,
|
|
131
|
+
self.api_key,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def browser(self) -> Browser:
|
|
136
|
+
if self._browser is None:
|
|
137
|
+
raise RuntimeError("BrowserSetup must be used as a context manager")
|
|
138
|
+
return self._browser
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
async def async_browser(self) -> AsyncBrowser:
|
|
142
|
+
if self._async_browser is None:
|
|
143
|
+
raise RuntimeError("BrowserSetup must be used as a context manager")
|
|
144
|
+
return self._async_browser
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def context(self) -> BrowserContext:
|
|
148
|
+
return self.browser.contexts[0]
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
async def async_context(self) -> AsyncBrowserContext:
|
|
152
|
+
return (await self.async_browser).contexts[0]
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def page(self) -> Page:
|
|
156
|
+
return self.context.pages[0]
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
async def async_page(self) -> AsyncPage:
|
|
160
|
+
return (await self.async_context).pages[0]
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def ai(self) -> Worker:
|
|
164
|
+
ai_service_worker = get_ai_service_worker(self.context)
|
|
165
|
+
if not ai_service_worker:
|
|
166
|
+
raise ValueError("AI service worker not found")
|
|
167
|
+
return ai_service_worker
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
async def async_ai(self) -> AsyncWorker:
|
|
171
|
+
ai_service_worker = await get_ai_service_worker_async(await self.async_context)
|
|
172
|
+
if not ai_service_worker:
|
|
173
|
+
raise ValueError("AI service worker not found")
|
|
174
|
+
return ai_service_worker
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class AgentTaskParams(TypedDict, total=False):
|
|
178
|
+
url: Optional[str]
|
|
179
|
+
output_schema: Optional[Dict[str, Any]]
|
|
180
|
+
on_agent_step: Optional[Callable[[str], None]]
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class BrowserTaskResponse(TypedDict):
|
|
184
|
+
session_id: str
|
|
185
|
+
task_result_task: Any
|
|
186
|
+
playwright_browser: Any
|
anchorbrowser/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
from .tools import (
|
|
4
|
+
ToolsResource,
|
|
5
|
+
AsyncToolsResource,
|
|
6
|
+
ToolsResourceWithRawResponse,
|
|
7
|
+
AsyncToolsResourceWithRawResponse,
|
|
8
|
+
ToolsResourceWithStreamingResponse,
|
|
9
|
+
AsyncToolsResourceWithStreamingResponse,
|
|
10
|
+
)
|
|
11
|
+
from .profiles import (
|
|
12
|
+
ProfilesResource,
|
|
13
|
+
AsyncProfilesResource,
|
|
14
|
+
ProfilesResourceWithRawResponse,
|
|
15
|
+
AsyncProfilesResourceWithRawResponse,
|
|
16
|
+
ProfilesResourceWithStreamingResponse,
|
|
17
|
+
AsyncProfilesResourceWithStreamingResponse,
|
|
18
|
+
)
|
|
19
|
+
from .sessions import (
|
|
20
|
+
SessionsResource,
|
|
21
|
+
AsyncSessionsResource,
|
|
22
|
+
SessionsResourceWithRawResponse,
|
|
23
|
+
AsyncSessionsResourceWithRawResponse,
|
|
24
|
+
SessionsResourceWithStreamingResponse,
|
|
25
|
+
AsyncSessionsResourceWithStreamingResponse,
|
|
26
|
+
)
|
|
27
|
+
from .extensions import (
|
|
28
|
+
ExtensionsResource,
|
|
29
|
+
AsyncExtensionsResource,
|
|
30
|
+
ExtensionsResourceWithRawResponse,
|
|
31
|
+
AsyncExtensionsResourceWithRawResponse,
|
|
32
|
+
ExtensionsResourceWithStreamingResponse,
|
|
33
|
+
AsyncExtensionsResourceWithStreamingResponse,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
"ProfilesResource",
|
|
38
|
+
"AsyncProfilesResource",
|
|
39
|
+
"ProfilesResourceWithRawResponse",
|
|
40
|
+
"AsyncProfilesResourceWithRawResponse",
|
|
41
|
+
"ProfilesResourceWithStreamingResponse",
|
|
42
|
+
"AsyncProfilesResourceWithStreamingResponse",
|
|
43
|
+
"SessionsResource",
|
|
44
|
+
"AsyncSessionsResource",
|
|
45
|
+
"SessionsResourceWithRawResponse",
|
|
46
|
+
"AsyncSessionsResourceWithRawResponse",
|
|
47
|
+
"SessionsResourceWithStreamingResponse",
|
|
48
|
+
"AsyncSessionsResourceWithStreamingResponse",
|
|
49
|
+
"ToolsResource",
|
|
50
|
+
"AsyncToolsResource",
|
|
51
|
+
"ToolsResourceWithRawResponse",
|
|
52
|
+
"AsyncToolsResourceWithRawResponse",
|
|
53
|
+
"ToolsResourceWithStreamingResponse",
|
|
54
|
+
"AsyncToolsResourceWithStreamingResponse",
|
|
55
|
+
"ExtensionsResource",
|
|
56
|
+
"AsyncExtensionsResource",
|
|
57
|
+
"ExtensionsResourceWithRawResponse",
|
|
58
|
+
"AsyncExtensionsResourceWithRawResponse",
|
|
59
|
+
"ExtensionsResourceWithStreamingResponse",
|
|
60
|
+
"AsyncExtensionsResourceWithStreamingResponse",
|
|
61
|
+
]
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from .._compat import cached_property
|
|
6
|
+
from .._resource import SyncAPIResource, AsyncAPIResource
|
|
7
|
+
from .._response import (
|
|
8
|
+
to_raw_response_wrapper,
|
|
9
|
+
to_streamed_response_wrapper,
|
|
10
|
+
async_to_raw_response_wrapper,
|
|
11
|
+
async_to_streamed_response_wrapper,
|
|
12
|
+
)
|
|
13
|
+
from ..lib.agent import on_agent_step_sync, create_task_payload, on_agent_step_async
|
|
14
|
+
from ..lib.browser import (
|
|
15
|
+
BrowserSetup,
|
|
16
|
+
AgentTaskParams,
|
|
17
|
+
BrowserTaskResponse,
|
|
18
|
+
)
|
|
19
|
+
from ..types.session_create_params import Session
|
|
20
|
+
|
|
21
|
+
__all__ = ["AgentResource", "AsyncAgentResource"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class AgentResource(SyncAPIResource):
|
|
25
|
+
@cached_property
|
|
26
|
+
def with_raw_response(self) -> AgentResourceWithRawResponse:
|
|
27
|
+
"""
|
|
28
|
+
This property can be used as a prefix for any HTTP method call to return
|
|
29
|
+
the raw response object instead of the parsed content.
|
|
30
|
+
|
|
31
|
+
For more information, see https://www.github.com/anchorbrowser/AnchorBrowser-SDK-Python#accessing-raw-response-data-eg-headers
|
|
32
|
+
"""
|
|
33
|
+
return AgentResourceWithRawResponse(self)
|
|
34
|
+
|
|
35
|
+
@cached_property
|
|
36
|
+
def with_streaming_response(self) -> AgentResourceWithStreamingResponse:
|
|
37
|
+
"""
|
|
38
|
+
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
|
39
|
+
|
|
40
|
+
For more information, see https://www.github.com/anchorbrowser/AnchorBrowser-SDK-Python#with_streaming_response
|
|
41
|
+
"""
|
|
42
|
+
return AgentResourceWithStreamingResponse(self)
|
|
43
|
+
|
|
44
|
+
def task(
|
|
45
|
+
self,
|
|
46
|
+
prompt: str,
|
|
47
|
+
*,
|
|
48
|
+
session_options: Optional[Session] = None,
|
|
49
|
+
task_options: Optional[AgentTaskParams] = None,
|
|
50
|
+
) -> str:
|
|
51
|
+
"""Execute an AI agent task within a browser session.
|
|
52
|
+
|
|
53
|
+
Creates a new browser session and executes the given prompt as an AI agent task.
|
|
54
|
+
The agent can optionally navigate to a specific URL and use a structured output schema.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
prompt (str): The task prompt/instruction for the AI agent to execute.
|
|
58
|
+
session_options (Optional[Session], optional): Configuration options for the
|
|
59
|
+
browser session. Defaults to None, which creates a session with default settings.
|
|
60
|
+
task_options (Optional[AgentTaskParams], optional): Additional task configuration
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
str: The result of the AI agent task execution.
|
|
64
|
+
"""
|
|
65
|
+
session = self._client.sessions.create(session=session_options or {})
|
|
66
|
+
if not session.data or not session.data.id:
|
|
67
|
+
raise ValueError("Failed to create session: No session ID returned")
|
|
68
|
+
|
|
69
|
+
with BrowserSetup(
|
|
70
|
+
session_id=session.data.id,
|
|
71
|
+
base_url=str(self._client.base_url),
|
|
72
|
+
api_key=self._client.api_key,
|
|
73
|
+
) as browser_setup:
|
|
74
|
+
output_schema = None
|
|
75
|
+
if task_options:
|
|
76
|
+
output_schema = task_options.get("output_schema")
|
|
77
|
+
url = task_options.get("url")
|
|
78
|
+
if url:
|
|
79
|
+
browser_setup.page.goto(url)
|
|
80
|
+
on_agent_step = task_options.get("on_agent_step")
|
|
81
|
+
if on_agent_step:
|
|
82
|
+
on_agent_step_sync(on_agent_step, browser_setup)
|
|
83
|
+
task_payload = create_task_payload(prompt, output_schema)
|
|
84
|
+
task_result = str(browser_setup.ai.evaluate(task_payload))
|
|
85
|
+
return task_result
|
|
86
|
+
|
|
87
|
+
def browser_task(
|
|
88
|
+
self,
|
|
89
|
+
prompt: str,
|
|
90
|
+
*,
|
|
91
|
+
session_options: Optional[Session] = None,
|
|
92
|
+
task_options: Optional[AgentTaskParams] = None,
|
|
93
|
+
) -> BrowserTaskResponse:
|
|
94
|
+
"""Execute an AI agent task and return a browser task response with session control.
|
|
95
|
+
|
|
96
|
+
Creates a new browser session, executes the given prompt as an AI agent task \n
|
|
97
|
+
returns a object that includes the session ID, task result, and browser instance for continued interaction by the caller. \n
|
|
98
|
+
This method differs from `task()` by returning control of the browser session to the caller rather than automatically closing it after task completion. \n
|
|
99
|
+
Args:
|
|
100
|
+
prompt (str): The task prompt/instruction for the AI agent to execute. \n
|
|
101
|
+
session_options (Optional[Session], optional): Configuration options for the browser session. Defaults to None, which creates a session with default settings. \n
|
|
102
|
+
task_options (Optional[AgentTaskParams], optional): Additional task configuration including: \n
|
|
103
|
+
- output_schema: Schema for structured output formatting
|
|
104
|
+
- url: URL to navigate to before executing the task
|
|
105
|
+
- on_agent_step: Callback function for agent step events
|
|
106
|
+
Defaults to None.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Response object containing:
|
|
110
|
+
- session_id: The ID of the created browser session
|
|
111
|
+
- task_result_task: The result of the AI agent task execution
|
|
112
|
+
- playwright_browser: Browser instance for continued interaction
|
|
113
|
+
"""
|
|
114
|
+
session = self._client.sessions.create(session=session_options or {})
|
|
115
|
+
if not session.data or not session.data.id:
|
|
116
|
+
raise ValueError("Failed to create session: No session ID returned")
|
|
117
|
+
|
|
118
|
+
with BrowserSetup(
|
|
119
|
+
session_id=session.data.id,
|
|
120
|
+
base_url=str(self._client.base_url),
|
|
121
|
+
api_key=self._client.api_key,
|
|
122
|
+
) as browser_setup:
|
|
123
|
+
output_schema = None
|
|
124
|
+
if task_options:
|
|
125
|
+
output_schema = task_options.get("output_schema")
|
|
126
|
+
url = task_options.get("url")
|
|
127
|
+
if url:
|
|
128
|
+
browser_setup.page.goto(url)
|
|
129
|
+
on_agent_step = task_options.get("on_agent_step")
|
|
130
|
+
if on_agent_step:
|
|
131
|
+
on_agent_step_sync(on_agent_step, browser_setup)
|
|
132
|
+
task_payload = create_task_payload(prompt, output_schema)
|
|
133
|
+
task_result = str(browser_setup.ai.evaluate(task_payload))
|
|
134
|
+
return BrowserTaskResponse(
|
|
135
|
+
session_id=session.data.id,
|
|
136
|
+
task_result_task=task_result,
|
|
137
|
+
playwright_browser=browser_setup.browser_generator,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class AsyncAgentResource(AsyncAPIResource):
|
|
142
|
+
@cached_property
|
|
143
|
+
def with_raw_response(self) -> AsyncAgentResourceWithRawResponse:
|
|
144
|
+
"""
|
|
145
|
+
This property can be used as a prefix for any HTTP method call to return
|
|
146
|
+
the raw response object instead of the parsed content.
|
|
147
|
+
|
|
148
|
+
For more information, see https://www.github.com/anchorbrowser/AnchorBrowser-SDK-Python#accessing-raw-response-data-eg-headers
|
|
149
|
+
"""
|
|
150
|
+
return AsyncAgentResourceWithRawResponse(self)
|
|
151
|
+
|
|
152
|
+
@cached_property
|
|
153
|
+
def with_streaming_response(self) -> AsyncAgentResourceWithStreamingResponse:
|
|
154
|
+
"""
|
|
155
|
+
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
|
156
|
+
|
|
157
|
+
For more information, see https://www.github.com/anchorbrowser/AnchorBrowser-SDK-Python#with_streaming_response
|
|
158
|
+
"""
|
|
159
|
+
return AsyncAgentResourceWithStreamingResponse(self)
|
|
160
|
+
|
|
161
|
+
async def task(
|
|
162
|
+
self,
|
|
163
|
+
prompt: str,
|
|
164
|
+
*,
|
|
165
|
+
session_options: Optional[Session] = None,
|
|
166
|
+
task_options: Optional[AgentTaskParams] = None,
|
|
167
|
+
) -> str:
|
|
168
|
+
"""Execute an AI agent task within a browser session.
|
|
169
|
+
|
|
170
|
+
Creates a new browser session and executes the given prompt as an AI agent task.
|
|
171
|
+
The agent can optionally navigate to a specific URL and use a structured output schema.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
prompt (str): The task prompt/instruction for the AI agent to execute.
|
|
175
|
+
session_options (Optional[Session], optional): Configuration options for the
|
|
176
|
+
browser session. Defaults to None, which creates a session with default settings.
|
|
177
|
+
task_options (Optional[AgentTaskParams], optional): Additional task configuration
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
str: The result of the AI agent task execution.
|
|
181
|
+
"""
|
|
182
|
+
session = await self._client.sessions.create(session=session_options or {})
|
|
183
|
+
if not session.data or not session.data.id:
|
|
184
|
+
raise ValueError("Failed to create session: No session ID returned")
|
|
185
|
+
|
|
186
|
+
browser_setup = BrowserSetup(
|
|
187
|
+
session_id=session.data.id,
|
|
188
|
+
base_url=str(self._client.base_url),
|
|
189
|
+
api_key=self._client.api_key,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
async with browser_setup:
|
|
193
|
+
output_schema = None
|
|
194
|
+
if task_options:
|
|
195
|
+
output_schema = task_options.get("output_schema")
|
|
196
|
+
url = task_options.get("url")
|
|
197
|
+
if url:
|
|
198
|
+
await (await browser_setup.async_page).goto(url)
|
|
199
|
+
on_agent_step = task_options.get("on_agent_step")
|
|
200
|
+
if on_agent_step:
|
|
201
|
+
on_agent_step_async(on_agent_step, browser_setup)
|
|
202
|
+
task_payload = create_task_payload(prompt, output_schema)
|
|
203
|
+
task_result = await (await browser_setup.async_ai).evaluate(task_payload)
|
|
204
|
+
return str(task_result)
|
|
205
|
+
|
|
206
|
+
async def browser_task(
|
|
207
|
+
self,
|
|
208
|
+
prompt: str,
|
|
209
|
+
*,
|
|
210
|
+
session_options: Optional[Session] = None,
|
|
211
|
+
task_options: Optional[AgentTaskParams] = None,
|
|
212
|
+
) -> BrowserTaskResponse:
|
|
213
|
+
"""Execute an AI agent task and return a browser task response with session control.
|
|
214
|
+
|
|
215
|
+
Creates a new browser session, executes the given prompt as an AI agent task \n
|
|
216
|
+
returns a object that includes the session ID, task result, and browser instance for continued interaction by the caller. \n
|
|
217
|
+
This method differs from `task()` by returning control of the browser session to the caller rather than automatically closing it after task completion. \n
|
|
218
|
+
Args:
|
|
219
|
+
prompt (str): The task prompt/instruction for the AI agent to execute. \n
|
|
220
|
+
session_options (Optional[Session], optional): Configuration options for the browser session. Defaults to None, which creates a session with default settings. \n
|
|
221
|
+
task_options (Optional[AgentTaskParams], optional): Additional task configuration including: \n
|
|
222
|
+
- output_schema: Schema for structured output formatting
|
|
223
|
+
- url: URL to navigate to before executing the task
|
|
224
|
+
- on_agent_step: Callback function for agent step events
|
|
225
|
+
Defaults to None.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Response object containing:
|
|
229
|
+
- session_id: The ID of the created browser session
|
|
230
|
+
- task_result_task: The result of the AI agent task execution
|
|
231
|
+
- playwright_browser: Browser instance for continued interaction
|
|
232
|
+
"""
|
|
233
|
+
session = await self._client.sessions.create(session=session_options or {})
|
|
234
|
+
if not session.data or not session.data.id:
|
|
235
|
+
raise ValueError("Failed to create session: No session ID returned")
|
|
236
|
+
|
|
237
|
+
async with BrowserSetup(
|
|
238
|
+
session_id=session.data.id,
|
|
239
|
+
base_url=str(self._client.base_url),
|
|
240
|
+
api_key=self._client.api_key,
|
|
241
|
+
) as browser_setup:
|
|
242
|
+
output_schema = None
|
|
243
|
+
if task_options:
|
|
244
|
+
output_schema = task_options.get("output_schema")
|
|
245
|
+
url = task_options.get("url")
|
|
246
|
+
if url:
|
|
247
|
+
await (await browser_setup.async_page).goto(url)
|
|
248
|
+
on_agent_step = task_options.get("on_agent_step")
|
|
249
|
+
if on_agent_step:
|
|
250
|
+
on_agent_step_async(on_agent_step, browser_setup)
|
|
251
|
+
task_payload = create_task_payload(prompt, output_schema)
|
|
252
|
+
task_result = await (await browser_setup.async_ai).evaluate(task_payload)
|
|
253
|
+
return BrowserTaskResponse(
|
|
254
|
+
session_id=session.data.id,
|
|
255
|
+
task_result_task=task_result,
|
|
256
|
+
playwright_browser=browser_setup.async_browser_generator,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class AgentResourceWithRawResponse:
|
|
261
|
+
def __init__(self, agent: AgentResource) -> None:
|
|
262
|
+
self._agent = agent
|
|
263
|
+
|
|
264
|
+
self.task = to_raw_response_wrapper(
|
|
265
|
+
agent.task,
|
|
266
|
+
)
|
|
267
|
+
self.browser_task = to_raw_response_wrapper(
|
|
268
|
+
agent.browser_task,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class AsyncAgentResourceWithRawResponse:
|
|
273
|
+
def __init__(self, agent: AsyncAgentResource) -> None:
|
|
274
|
+
self._agent = agent
|
|
275
|
+
|
|
276
|
+
self.task = async_to_raw_response_wrapper(
|
|
277
|
+
agent.task,
|
|
278
|
+
)
|
|
279
|
+
self.browser_task = async_to_raw_response_wrapper(
|
|
280
|
+
agent.browser_task,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class AgentResourceWithStreamingResponse:
|
|
285
|
+
def __init__(self, agent: AgentResource) -> None:
|
|
286
|
+
self._agent = agent
|
|
287
|
+
|
|
288
|
+
self.task = to_streamed_response_wrapper(
|
|
289
|
+
agent.task,
|
|
290
|
+
)
|
|
291
|
+
self.browser_task = to_streamed_response_wrapper(
|
|
292
|
+
agent.browser_task,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class AsyncAgentResourceWithStreamingResponse:
|
|
297
|
+
def __init__(self, agent: AsyncAgentResource) -> None:
|
|
298
|
+
self._agent = agent
|
|
299
|
+
|
|
300
|
+
self.task = async_to_streamed_response_wrapper(
|
|
301
|
+
agent.task,
|
|
302
|
+
)
|
|
303
|
+
self.browser_task = async_to_streamed_response_wrapper(
|
|
304
|
+
agent.browser_task,
|
|
305
|
+
)
|