optexity-browser-use 0.9.5__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.
- browser_use/__init__.py +157 -0
- browser_use/actor/__init__.py +11 -0
- browser_use/actor/element.py +1175 -0
- browser_use/actor/mouse.py +134 -0
- browser_use/actor/page.py +561 -0
- browser_use/actor/playground/flights.py +41 -0
- browser_use/actor/playground/mixed_automation.py +54 -0
- browser_use/actor/playground/playground.py +236 -0
- browser_use/actor/utils.py +176 -0
- browser_use/agent/cloud_events.py +282 -0
- browser_use/agent/gif.py +424 -0
- browser_use/agent/judge.py +170 -0
- browser_use/agent/message_manager/service.py +473 -0
- browser_use/agent/message_manager/utils.py +52 -0
- browser_use/agent/message_manager/views.py +98 -0
- browser_use/agent/prompts.py +413 -0
- browser_use/agent/service.py +2316 -0
- browser_use/agent/system_prompt.md +185 -0
- browser_use/agent/system_prompt_flash.md +10 -0
- browser_use/agent/system_prompt_no_thinking.md +183 -0
- browser_use/agent/views.py +743 -0
- browser_use/browser/__init__.py +41 -0
- browser_use/browser/cloud/cloud.py +203 -0
- browser_use/browser/cloud/views.py +89 -0
- browser_use/browser/events.py +578 -0
- browser_use/browser/profile.py +1158 -0
- browser_use/browser/python_highlights.py +548 -0
- browser_use/browser/session.py +3225 -0
- browser_use/browser/session_manager.py +399 -0
- browser_use/browser/video_recorder.py +162 -0
- browser_use/browser/views.py +200 -0
- browser_use/browser/watchdog_base.py +260 -0
- browser_use/browser/watchdogs/__init__.py +0 -0
- browser_use/browser/watchdogs/aboutblank_watchdog.py +253 -0
- browser_use/browser/watchdogs/crash_watchdog.py +335 -0
- browser_use/browser/watchdogs/default_action_watchdog.py +2729 -0
- browser_use/browser/watchdogs/dom_watchdog.py +817 -0
- browser_use/browser/watchdogs/downloads_watchdog.py +1277 -0
- browser_use/browser/watchdogs/local_browser_watchdog.py +461 -0
- browser_use/browser/watchdogs/permissions_watchdog.py +43 -0
- browser_use/browser/watchdogs/popups_watchdog.py +143 -0
- browser_use/browser/watchdogs/recording_watchdog.py +126 -0
- browser_use/browser/watchdogs/screenshot_watchdog.py +62 -0
- browser_use/browser/watchdogs/security_watchdog.py +280 -0
- browser_use/browser/watchdogs/storage_state_watchdog.py +335 -0
- browser_use/cli.py +2359 -0
- browser_use/code_use/__init__.py +16 -0
- browser_use/code_use/formatting.py +192 -0
- browser_use/code_use/namespace.py +665 -0
- browser_use/code_use/notebook_export.py +276 -0
- browser_use/code_use/service.py +1340 -0
- browser_use/code_use/system_prompt.md +574 -0
- browser_use/code_use/utils.py +150 -0
- browser_use/code_use/views.py +171 -0
- browser_use/config.py +505 -0
- browser_use/controller/__init__.py +3 -0
- browser_use/dom/enhanced_snapshot.py +161 -0
- browser_use/dom/markdown_extractor.py +169 -0
- browser_use/dom/playground/extraction.py +312 -0
- browser_use/dom/playground/multi_act.py +32 -0
- browser_use/dom/serializer/clickable_elements.py +200 -0
- browser_use/dom/serializer/code_use_serializer.py +287 -0
- browser_use/dom/serializer/eval_serializer.py +478 -0
- browser_use/dom/serializer/html_serializer.py +212 -0
- browser_use/dom/serializer/paint_order.py +197 -0
- browser_use/dom/serializer/serializer.py +1170 -0
- browser_use/dom/service.py +825 -0
- browser_use/dom/utils.py +129 -0
- browser_use/dom/views.py +906 -0
- browser_use/exceptions.py +5 -0
- browser_use/filesystem/__init__.py +0 -0
- browser_use/filesystem/file_system.py +619 -0
- browser_use/init_cmd.py +376 -0
- browser_use/integrations/gmail/__init__.py +24 -0
- browser_use/integrations/gmail/actions.py +115 -0
- browser_use/integrations/gmail/service.py +225 -0
- browser_use/llm/__init__.py +155 -0
- browser_use/llm/anthropic/chat.py +242 -0
- browser_use/llm/anthropic/serializer.py +312 -0
- browser_use/llm/aws/__init__.py +36 -0
- browser_use/llm/aws/chat_anthropic.py +242 -0
- browser_use/llm/aws/chat_bedrock.py +289 -0
- browser_use/llm/aws/serializer.py +257 -0
- browser_use/llm/azure/chat.py +91 -0
- browser_use/llm/base.py +57 -0
- browser_use/llm/browser_use/__init__.py +3 -0
- browser_use/llm/browser_use/chat.py +201 -0
- browser_use/llm/cerebras/chat.py +193 -0
- browser_use/llm/cerebras/serializer.py +109 -0
- browser_use/llm/deepseek/chat.py +212 -0
- browser_use/llm/deepseek/serializer.py +109 -0
- browser_use/llm/exceptions.py +29 -0
- browser_use/llm/google/__init__.py +3 -0
- browser_use/llm/google/chat.py +542 -0
- browser_use/llm/google/serializer.py +120 -0
- browser_use/llm/groq/chat.py +229 -0
- browser_use/llm/groq/parser.py +158 -0
- browser_use/llm/groq/serializer.py +159 -0
- browser_use/llm/messages.py +238 -0
- browser_use/llm/models.py +271 -0
- browser_use/llm/oci_raw/__init__.py +10 -0
- browser_use/llm/oci_raw/chat.py +443 -0
- browser_use/llm/oci_raw/serializer.py +229 -0
- browser_use/llm/ollama/chat.py +97 -0
- browser_use/llm/ollama/serializer.py +143 -0
- browser_use/llm/openai/chat.py +264 -0
- browser_use/llm/openai/like.py +15 -0
- browser_use/llm/openai/serializer.py +165 -0
- browser_use/llm/openrouter/chat.py +211 -0
- browser_use/llm/openrouter/serializer.py +26 -0
- browser_use/llm/schema.py +176 -0
- browser_use/llm/views.py +48 -0
- browser_use/logging_config.py +330 -0
- browser_use/mcp/__init__.py +18 -0
- browser_use/mcp/__main__.py +12 -0
- browser_use/mcp/client.py +544 -0
- browser_use/mcp/controller.py +264 -0
- browser_use/mcp/server.py +1114 -0
- browser_use/observability.py +204 -0
- browser_use/py.typed +0 -0
- browser_use/sandbox/__init__.py +41 -0
- browser_use/sandbox/sandbox.py +637 -0
- browser_use/sandbox/views.py +132 -0
- browser_use/screenshots/__init__.py +1 -0
- browser_use/screenshots/service.py +52 -0
- browser_use/sync/__init__.py +6 -0
- browser_use/sync/auth.py +357 -0
- browser_use/sync/service.py +161 -0
- browser_use/telemetry/__init__.py +51 -0
- browser_use/telemetry/service.py +112 -0
- browser_use/telemetry/views.py +101 -0
- browser_use/tokens/__init__.py +0 -0
- browser_use/tokens/custom_pricing.py +24 -0
- browser_use/tokens/mappings.py +4 -0
- browser_use/tokens/service.py +580 -0
- browser_use/tokens/views.py +108 -0
- browser_use/tools/registry/service.py +572 -0
- browser_use/tools/registry/views.py +174 -0
- browser_use/tools/service.py +1675 -0
- browser_use/tools/utils.py +82 -0
- browser_use/tools/views.py +100 -0
- browser_use/utils.py +670 -0
- optexity_browser_use-0.9.5.dist-info/METADATA +344 -0
- optexity_browser_use-0.9.5.dist-info/RECORD +147 -0
- optexity_browser_use-0.9.5.dist-info/WHEEL +4 -0
- optexity_browser_use-0.9.5.dist-info/entry_points.txt +3 -0
- optexity_browser_use-0.9.5.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Code-use mode - Jupyter notebook-like code execution for browser automation."""
|
|
2
|
+
|
|
3
|
+
from browser_use.code_use.namespace import create_namespace
|
|
4
|
+
from browser_use.code_use.notebook_export import export_to_ipynb, session_to_python_script
|
|
5
|
+
from browser_use.code_use.service import CodeAgent
|
|
6
|
+
from browser_use.code_use.views import CodeCell, ExecutionStatus, NotebookSession
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
'CodeAgent',
|
|
10
|
+
'create_namespace',
|
|
11
|
+
'export_to_ipynb',
|
|
12
|
+
'session_to_python_script',
|
|
13
|
+
'CodeCell',
|
|
14
|
+
'ExecutionStatus',
|
|
15
|
+
'NotebookSession',
|
|
16
|
+
]
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Browser state formatting helpers for code-use agent."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from browser_use.browser.session import BrowserSession
|
|
7
|
+
from browser_use.browser.views import BrowserStateSummary
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def format_browser_state_for_llm(
|
|
13
|
+
state: BrowserStateSummary,
|
|
14
|
+
namespace: dict[str, Any],
|
|
15
|
+
browser_session: BrowserSession,
|
|
16
|
+
) -> str:
|
|
17
|
+
"""
|
|
18
|
+
Format browser state summary for LLM consumption in code-use mode.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
state: Browser state summary from browser_session.get_browser_state_summary()
|
|
22
|
+
namespace: The code execution namespace (for showing available variables)
|
|
23
|
+
browser_session: Browser session for additional checks (jQuery, etc.)
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Formatted browser state text for LLM
|
|
27
|
+
"""
|
|
28
|
+
assert state.dom_state is not None
|
|
29
|
+
dom_state = state.dom_state
|
|
30
|
+
|
|
31
|
+
# Use eval_representation (compact serializer for code agents)
|
|
32
|
+
dom_html = dom_state.eval_representation()
|
|
33
|
+
if dom_html == '':
|
|
34
|
+
dom_html = 'Empty DOM tree (you might have to wait for the page to load)'
|
|
35
|
+
|
|
36
|
+
# Format with URL and title header
|
|
37
|
+
lines = ['## Browser State']
|
|
38
|
+
lines.append(f'**URL:** {state.url}')
|
|
39
|
+
lines.append(f'**Title:** {state.title}')
|
|
40
|
+
lines.append('')
|
|
41
|
+
|
|
42
|
+
# Add tabs info if multiple tabs exist
|
|
43
|
+
if len(state.tabs) > 1:
|
|
44
|
+
lines.append('**Tabs:**')
|
|
45
|
+
current_target_candidates = []
|
|
46
|
+
# Find tabs that match current URL and title
|
|
47
|
+
for tab in state.tabs:
|
|
48
|
+
if tab.url == state.url and tab.title == state.title:
|
|
49
|
+
current_target_candidates.append(tab.target_id)
|
|
50
|
+
current_target_id = current_target_candidates[0] if len(current_target_candidates) == 1 else None
|
|
51
|
+
|
|
52
|
+
for tab in state.tabs:
|
|
53
|
+
is_current = ' (current)' if tab.target_id == current_target_id else ''
|
|
54
|
+
lines.append(f' - Tab {tab.target_id[-4:]}: {tab.url} - {tab.title[:30]}{is_current}')
|
|
55
|
+
lines.append('')
|
|
56
|
+
|
|
57
|
+
# Add page scroll info if available
|
|
58
|
+
if state.page_info:
|
|
59
|
+
pi = state.page_info
|
|
60
|
+
pages_above = pi.pixels_above / pi.viewport_height if pi.viewport_height > 0 else 0
|
|
61
|
+
pages_below = pi.pixels_below / pi.viewport_height if pi.viewport_height > 0 else 0
|
|
62
|
+
total_pages = pi.page_height / pi.viewport_height if pi.viewport_height > 0 else 0
|
|
63
|
+
|
|
64
|
+
scroll_info = f'**Page:** {pages_above:.1f} pages above, {pages_below:.1f} pages below'
|
|
65
|
+
if total_pages > 1.2: # Only mention total if significantly > 1 page
|
|
66
|
+
scroll_info += f', {total_pages:.1f} total pages'
|
|
67
|
+
lines.append(scroll_info)
|
|
68
|
+
lines.append('')
|
|
69
|
+
|
|
70
|
+
# Add network loading info if there are pending requests
|
|
71
|
+
if state.pending_network_requests:
|
|
72
|
+
# Remove duplicates by URL (keep first occurrence with earliest duration)
|
|
73
|
+
seen_urls = set()
|
|
74
|
+
unique_requests = []
|
|
75
|
+
for req in state.pending_network_requests:
|
|
76
|
+
if req.url not in seen_urls:
|
|
77
|
+
seen_urls.add(req.url)
|
|
78
|
+
unique_requests.append(req)
|
|
79
|
+
|
|
80
|
+
lines.append(f'**⏳ Loading:** {len(unique_requests)} network requests still loading')
|
|
81
|
+
# Show up to 20 unique requests with truncated URLs (30 chars max)
|
|
82
|
+
for req in unique_requests[:20]:
|
|
83
|
+
duration_sec = req.loading_duration_ms / 1000
|
|
84
|
+
url_display = req.url if len(req.url) <= 30 else req.url[:27] + '...'
|
|
85
|
+
logger.info(f' - [{duration_sec:.1f}s] {url_display}')
|
|
86
|
+
lines.append(f' - [{duration_sec:.1f}s] {url_display}')
|
|
87
|
+
if len(unique_requests) > 20:
|
|
88
|
+
lines.append(f' - ... and {len(unique_requests) - 20} more')
|
|
89
|
+
lines.append('**Tip:** Content may still be loading. Consider waiting with `await asyncio.sleep(1)` if data is missing.')
|
|
90
|
+
lines.append('')
|
|
91
|
+
|
|
92
|
+
# Add available variables and functions BEFORE DOM structure
|
|
93
|
+
# Show useful utilities (json, asyncio, etc.) and user-defined vars, but hide system objects
|
|
94
|
+
skip_vars = {
|
|
95
|
+
'browser',
|
|
96
|
+
'file_system', # System objects
|
|
97
|
+
'np',
|
|
98
|
+
'pd',
|
|
99
|
+
'plt',
|
|
100
|
+
'numpy',
|
|
101
|
+
'pandas',
|
|
102
|
+
'matplotlib',
|
|
103
|
+
'requests',
|
|
104
|
+
'BeautifulSoup',
|
|
105
|
+
'bs4',
|
|
106
|
+
'pypdf',
|
|
107
|
+
'PdfReader',
|
|
108
|
+
'wait',
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# Highlight code block variables separately from regular variables
|
|
112
|
+
code_block_vars = []
|
|
113
|
+
regular_vars = []
|
|
114
|
+
tracked_code_blocks = namespace.get('_code_block_vars', set())
|
|
115
|
+
for name in namespace.keys():
|
|
116
|
+
# Skip private vars and system objects/actions
|
|
117
|
+
if not name.startswith('_') and name not in skip_vars:
|
|
118
|
+
if name in tracked_code_blocks:
|
|
119
|
+
code_block_vars.append(name)
|
|
120
|
+
else:
|
|
121
|
+
regular_vars.append(name)
|
|
122
|
+
|
|
123
|
+
# Sort for consistent display
|
|
124
|
+
available_vars_sorted = sorted(regular_vars)
|
|
125
|
+
code_block_vars_sorted = sorted(code_block_vars)
|
|
126
|
+
|
|
127
|
+
# Build available line with code blocks and variables
|
|
128
|
+
parts = []
|
|
129
|
+
if code_block_vars_sorted:
|
|
130
|
+
# Show detailed info for code block variables
|
|
131
|
+
code_block_details = []
|
|
132
|
+
for var_name in code_block_vars_sorted:
|
|
133
|
+
value = namespace.get(var_name)
|
|
134
|
+
if value is not None:
|
|
135
|
+
type_name = type(value).__name__
|
|
136
|
+
value_str = str(value) if not isinstance(value, str) else value
|
|
137
|
+
|
|
138
|
+
# Check if it's a function (starts with "(function" or "(async function")
|
|
139
|
+
is_function = value_str.strip().startswith('(function') or value_str.strip().startswith('(async function')
|
|
140
|
+
|
|
141
|
+
if is_function:
|
|
142
|
+
# For functions, only show name and type
|
|
143
|
+
detail = f'{var_name}({type_name})'
|
|
144
|
+
else:
|
|
145
|
+
# For non-functions, show first and last 20 chars
|
|
146
|
+
first_20 = value_str[:20].replace('\n', '\\n').replace('\t', '\\t')
|
|
147
|
+
last_20 = value_str[-20:].replace('\n', '\\n').replace('\t', '\\t') if len(value_str) > 20 else ''
|
|
148
|
+
|
|
149
|
+
if last_20 and first_20 != last_20:
|
|
150
|
+
detail = f'{var_name}({type_name}): "{first_20}...{last_20}"'
|
|
151
|
+
else:
|
|
152
|
+
detail = f'{var_name}({type_name}): "{first_20}"'
|
|
153
|
+
code_block_details.append(detail)
|
|
154
|
+
|
|
155
|
+
parts.append(f'**Code block variables:** {" | ".join(code_block_details)}')
|
|
156
|
+
if available_vars_sorted:
|
|
157
|
+
parts.append(f'**Variables:** {", ".join(available_vars_sorted)}')
|
|
158
|
+
|
|
159
|
+
lines.append(f'**Available:** {" | ".join(parts)}')
|
|
160
|
+
lines.append('')
|
|
161
|
+
|
|
162
|
+
# Add DOM structure
|
|
163
|
+
lines.append('**DOM Structure:**')
|
|
164
|
+
|
|
165
|
+
# Add scroll position hints for DOM
|
|
166
|
+
if state.page_info:
|
|
167
|
+
pi = state.page_info
|
|
168
|
+
pages_above = pi.pixels_above / pi.viewport_height if pi.viewport_height > 0 else 0
|
|
169
|
+
pages_below = pi.pixels_below / pi.viewport_height if pi.viewport_height > 0 else 0
|
|
170
|
+
|
|
171
|
+
if pages_above > 0:
|
|
172
|
+
dom_html = f'... {pages_above:.1f} pages above \n{dom_html}'
|
|
173
|
+
else:
|
|
174
|
+
dom_html = '[Start of page]\n' + dom_html
|
|
175
|
+
|
|
176
|
+
if pages_below > 0:
|
|
177
|
+
dom_html += f'\n... {pages_below:.1f} pages below '
|
|
178
|
+
else:
|
|
179
|
+
dom_html += '\n[End of page]'
|
|
180
|
+
|
|
181
|
+
# Truncate DOM if too long and notify LLM
|
|
182
|
+
max_dom_length = 60000
|
|
183
|
+
if len(dom_html) > max_dom_length:
|
|
184
|
+
lines.append(dom_html[:max_dom_length])
|
|
185
|
+
lines.append(
|
|
186
|
+
f'\n[DOM truncated after {max_dom_length} characters. Full page contains {len(dom_html)} characters total. Use evaluate to explore more.]'
|
|
187
|
+
)
|
|
188
|
+
else:
|
|
189
|
+
lines.append(dom_html)
|
|
190
|
+
|
|
191
|
+
browser_state_text = '\n'.join(lines)
|
|
192
|
+
return browser_state_text
|