vibesurf 0.1.7__py3-none-any.whl → 0.1.9__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.
Potentially problematic release.
This version of vibesurf might be problematic. Click here for more details.
- vibe_surf/_version.py +2 -2
- vibe_surf/agents/browser_use_agent.py +48 -154
- vibe_surf/agents/vibe_surf_agent.py +10 -9
- vibe_surf/backend/shared_state.py +1 -1
- vibe_surf/backend/utils/encryption.py +5 -35
- vibe_surf/browser/agen_browser_profile.py +3 -4
- vibe_surf/browser/agent_browser_session.py +115 -52
- vibe_surf/browser/browser_manager.py +2 -2
- vibe_surf/browser/utils.py +8 -15
- vibe_surf/browser/watchdogs/action_watchdog.py +8 -194
- vibe_surf/browser/watchdogs/dom_watchdog.py +3 -675
- vibe_surf/cli.py +9 -2
- vibe_surf/controller/mcp_client.py +0 -4
- vibe_surf/controller/{vibesurf_controller.py → vibesurf_tools.py} +13 -48
- {vibesurf-0.1.7.dist-info → vibesurf-0.1.9.dist-info}/METADATA +8 -3
- {vibesurf-0.1.7.dist-info → vibesurf-0.1.9.dist-info}/RECORD +20 -20
- {vibesurf-0.1.7.dist-info → vibesurf-0.1.9.dist-info}/WHEEL +0 -0
- {vibesurf-0.1.7.dist-info → vibesurf-0.1.9.dist-info}/entry_points.txt +0 -0
- {vibesurf-0.1.7.dist-info → vibesurf-0.1.9.dist-info}/licenses/LICENSE +0 -0
- {vibesurf-0.1.7.dist-info → vibesurf-0.1.9.dist-info}/top_level.txt +0 -0
vibe_surf/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.9'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 9)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -53,12 +53,12 @@ from browser_use.agent.views import (
|
|
|
53
53
|
StepMetadata,
|
|
54
54
|
)
|
|
55
55
|
from pydantic import BaseModel, ConfigDict, Field, ValidationError, create_model, model_validator
|
|
56
|
-
from browser_use
|
|
56
|
+
from browser_use import Browser, BrowserProfile, BrowserSession
|
|
57
57
|
from browser_use.browser.session import DEFAULT_BROWSER_PROFILE
|
|
58
58
|
from browser_use.browser.views import BrowserStateSummary
|
|
59
59
|
from browser_use.config import CONFIG
|
|
60
|
-
from browser_use.
|
|
61
|
-
from browser_use.
|
|
60
|
+
from browser_use.tools.registry.views import ActionModel
|
|
61
|
+
from browser_use.tools.service import Controller, Tools
|
|
62
62
|
from browser_use.dom.views import DOMInteractedElement
|
|
63
63
|
from browser_use.filesystem.file_system import FileSystem
|
|
64
64
|
from browser_use.observability import observe, observe_debug
|
|
@@ -79,45 +79,6 @@ from vibe_surf.controller.file_system import CustomFileSystem
|
|
|
79
79
|
Context = TypeVar('Context')
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
def log_response(response: AgentOutput, registry=None, logger=None) -> None:
|
|
83
|
-
"""Utility function to log the model's response."""
|
|
84
|
-
|
|
85
|
-
# Use module logger if no logger provided
|
|
86
|
-
if logger is None:
|
|
87
|
-
logger = logging.getLogger(__name__)
|
|
88
|
-
|
|
89
|
-
# Only log thinking if it's present
|
|
90
|
-
if response.current_state.thinking:
|
|
91
|
-
logger.info(f'💡 Thinking:\n{response.current_state.thinking}')
|
|
92
|
-
|
|
93
|
-
# Only log evaluation if it's not empty
|
|
94
|
-
eval_goal = response.current_state.evaluation_previous_goal
|
|
95
|
-
if eval_goal:
|
|
96
|
-
if 'success' in eval_goal.lower():
|
|
97
|
-
emoji = '👍'
|
|
98
|
-
# Green color for success
|
|
99
|
-
logger.info(f' \033[32m{emoji} Eval: {eval_goal}\033[0m')
|
|
100
|
-
elif 'failure' in eval_goal.lower():
|
|
101
|
-
emoji = '⚠️'
|
|
102
|
-
# Red color for failure
|
|
103
|
-
logger.info(f' \033[31m{emoji} Eval: {eval_goal}\033[0m')
|
|
104
|
-
else:
|
|
105
|
-
emoji = '❔'
|
|
106
|
-
# No color for unknown/neutral
|
|
107
|
-
logger.info(f' {emoji} Eval: {eval_goal}')
|
|
108
|
-
|
|
109
|
-
# Always log memory if present
|
|
110
|
-
if response.current_state.memory:
|
|
111
|
-
logger.debug(f'🧠 Memory: {response.current_state.memory}')
|
|
112
|
-
|
|
113
|
-
# Only log next goal if it's not empty
|
|
114
|
-
next_goal = response.current_state.next_goal
|
|
115
|
-
if next_goal:
|
|
116
|
-
# Blue color for next goal
|
|
117
|
-
logger.info(f' \033[34m🎯 Next goal: {next_goal}\033[0m')
|
|
118
|
-
else:
|
|
119
|
-
logger.info('') # Add empty line for spacing
|
|
120
|
-
|
|
121
82
|
|
|
122
83
|
class BrowserUseAgent(Agent):
|
|
123
84
|
@time_execution_sync('--init')
|
|
@@ -128,7 +89,9 @@ class BrowserUseAgent(Agent):
|
|
|
128
89
|
# Optional parameters
|
|
129
90
|
browser_profile: BrowserProfile | None = None,
|
|
130
91
|
browser_session: BrowserSession | None = None,
|
|
131
|
-
|
|
92
|
+
browser: Browser | None = None, # Alias for browser_session
|
|
93
|
+
tools: Tools[Context] | None = None,
|
|
94
|
+
controller: Tools[Context] | None = None, # Alias for tools
|
|
132
95
|
# Initial agent run parameters
|
|
133
96
|
sensitive_data: dict[str, str | dict[str, str]] | None = None,
|
|
134
97
|
initial_actions: list[dict[str, dict[str, Any]]] | None = None,
|
|
@@ -147,14 +110,11 @@ class BrowserUseAgent(Agent):
|
|
|
147
110
|
# Agent settings
|
|
148
111
|
output_model_schema: type[AgentStructuredOutput] | None = None,
|
|
149
112
|
use_vision: bool = True,
|
|
150
|
-
use_vision_for_planner: bool = False, # Deprecated
|
|
151
113
|
save_conversation_path: str | Path | None = None,
|
|
152
114
|
save_conversation_path_encoding: str | None = 'utf-8',
|
|
153
115
|
max_failures: int = 3,
|
|
154
|
-
retry_delay: int = 10,
|
|
155
116
|
override_system_message: str | None = None,
|
|
156
117
|
extend_system_message: str | None = None,
|
|
157
|
-
validate_output: bool = False,
|
|
158
118
|
generate_gif: bool | str = False,
|
|
159
119
|
available_file_paths: list[str] | None = None,
|
|
160
120
|
include_attributes: list[str] | None = None,
|
|
@@ -163,12 +123,7 @@ class BrowserUseAgent(Agent):
|
|
|
163
123
|
flash_mode: bool = False,
|
|
164
124
|
max_history_items: int | None = None,
|
|
165
125
|
page_extraction_llm: BaseChatModel | None = None,
|
|
166
|
-
planner_llm: BaseChatModel | None = None, # Deprecated
|
|
167
|
-
planner_interval: int = 1, # Deprecated
|
|
168
|
-
is_planner_reasoning: bool = False, # Deprecated
|
|
169
|
-
extend_planner_system_message: str | None = None, # Deprecated
|
|
170
126
|
injected_agent_state: AgentState | None = None,
|
|
171
|
-
context: Context | None = None,
|
|
172
127
|
source: str | None = None,
|
|
173
128
|
file_system_path: str | None = None,
|
|
174
129
|
task_id: str | None = None,
|
|
@@ -179,38 +134,11 @@ class BrowserUseAgent(Agent):
|
|
|
179
134
|
vision_detail_level: Literal['auto', 'low', 'high'] = 'auto',
|
|
180
135
|
llm_timeout: int = 90,
|
|
181
136
|
step_timeout: int = 120,
|
|
182
|
-
|
|
137
|
+
directly_open_url: bool = True,
|
|
183
138
|
include_recent_events: bool = False,
|
|
184
139
|
allow_parallel_action_types: list[str] = ["extract_structured_data", "extract_content_from_file"],
|
|
185
140
|
**kwargs,
|
|
186
141
|
):
|
|
187
|
-
if not isinstance(llm, BaseChatModel):
|
|
188
|
-
raise ValueError('invalid llm, must be from browser_use.llm')
|
|
189
|
-
# Check for deprecated planner parameters
|
|
190
|
-
planner_params = [
|
|
191
|
-
planner_llm,
|
|
192
|
-
use_vision_for_planner,
|
|
193
|
-
is_planner_reasoning,
|
|
194
|
-
extend_planner_system_message,
|
|
195
|
-
]
|
|
196
|
-
if any(param is not None and param is not False for param in planner_params) or planner_interval != 1:
|
|
197
|
-
self.logger.warning(
|
|
198
|
-
'⚠️ Planner functionality has been removed in browser-use v0.3.3+. '
|
|
199
|
-
'The planner_llm, use_vision_for_planner, planner_interval, is_planner_reasoning, '
|
|
200
|
-
'and extend_planner_system_message parameters are deprecated and will be ignored. '
|
|
201
|
-
'Please remove these parameters from your Agent() initialization.'
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
# Check for deprecated memory parameters
|
|
205
|
-
if kwargs.get('enable_memory', False) or kwargs.get('memory_config') is not None:
|
|
206
|
-
self.logger.warning(
|
|
207
|
-
'Memory support has been removed as of version 0.3.2. '
|
|
208
|
-
'The agent context for memory is significantly improved and no longer requires the old memory system. '
|
|
209
|
-
"Please remove the 'enable_memory' and 'memory_config' parameters."
|
|
210
|
-
)
|
|
211
|
-
kwargs['enable_memory'] = False
|
|
212
|
-
kwargs['memory_config'] = None
|
|
213
|
-
|
|
214
142
|
if page_extraction_llm is None:
|
|
215
143
|
page_extraction_llm = llm
|
|
216
144
|
if available_file_paths is None:
|
|
@@ -221,39 +149,49 @@ class BrowserUseAgent(Agent):
|
|
|
221
149
|
self.session_id: str = uuid7str()
|
|
222
150
|
self.allow_parallel_action_types = allow_parallel_action_types
|
|
223
151
|
|
|
152
|
+
browser_profile = browser_profile or DEFAULT_BROWSER_PROFILE
|
|
153
|
+
|
|
154
|
+
# Handle browser vs browser_session parameter (browser takes precedence)
|
|
155
|
+
if browser and browser_session:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
'Cannot specify both "browser" and "browser_session" parameters. Use "browser" for the cleaner API.')
|
|
158
|
+
browser_session = browser or browser_session
|
|
159
|
+
|
|
160
|
+
self.browser_session = browser_session or BrowserSession(
|
|
161
|
+
browser_profile=browser_profile,
|
|
162
|
+
id=uuid7str()[:-4] + self.id[-4:], # re-use the same 4-char suffix so they show up together in logs
|
|
163
|
+
)
|
|
164
|
+
|
|
224
165
|
# Initialize available file paths as direct attribute
|
|
225
166
|
self.available_file_paths = available_file_paths
|
|
226
167
|
|
|
227
|
-
# Temporary logger for initialization (will be replaced by property)
|
|
228
|
-
self._logger = None
|
|
229
|
-
|
|
230
168
|
# Core components
|
|
231
169
|
self.task = task
|
|
232
170
|
self.llm = llm
|
|
233
|
-
self.
|
|
171
|
+
self.directly_open_url = directly_open_url
|
|
234
172
|
self.include_recent_events = include_recent_events
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
173
|
+
if tools is not None:
|
|
174
|
+
self.tools = tools
|
|
175
|
+
elif controller is not None:
|
|
176
|
+
self.tools = controller
|
|
177
|
+
else:
|
|
178
|
+
self.tools = Tools(display_files_in_done_text=display_files_in_done_text)
|
|
238
179
|
|
|
239
180
|
# Structured output
|
|
240
181
|
self.output_model_schema = output_model_schema
|
|
241
182
|
if self.output_model_schema is not None:
|
|
242
|
-
self.
|
|
183
|
+
self.tools.use_structured_output_action(self.output_model_schema)
|
|
243
184
|
|
|
244
185
|
self.sensitive_data = sensitive_data
|
|
245
186
|
|
|
246
187
|
self.settings = AgentSettings(
|
|
247
188
|
use_vision=use_vision,
|
|
248
189
|
vision_detail_level=vision_detail_level,
|
|
249
|
-
use_vision_for_planner=False, # Always False now (deprecated)
|
|
250
190
|
save_conversation_path=save_conversation_path,
|
|
251
191
|
save_conversation_path_encoding=save_conversation_path_encoding,
|
|
252
192
|
max_failures=max_failures,
|
|
253
|
-
retry_delay=retry_delay,
|
|
254
193
|
override_system_message=override_system_message,
|
|
255
194
|
extend_system_message=extend_system_message,
|
|
256
|
-
validate_output=validate_output,
|
|
257
195
|
generate_gif=generate_gif,
|
|
258
196
|
include_attributes=include_attributes,
|
|
259
197
|
max_actions_per_step=max_actions_per_step,
|
|
@@ -261,10 +199,6 @@ class BrowserUseAgent(Agent):
|
|
|
261
199
|
flash_mode=flash_mode,
|
|
262
200
|
max_history_items=max_history_items,
|
|
263
201
|
page_extraction_llm=page_extraction_llm,
|
|
264
|
-
planner_llm=None, # Always None now (deprecated)
|
|
265
|
-
planner_interval=1, # Always 1 now (deprecated)
|
|
266
|
-
is_planner_reasoning=False, # Always False now (deprecated)
|
|
267
|
-
extend_planner_system_message=None, # Always None now (deprecated)
|
|
268
202
|
calculate_cost=calculate_cost,
|
|
269
203
|
include_tool_call_examples=include_tool_call_examples,
|
|
270
204
|
llm_timeout=llm_timeout,
|
|
@@ -275,7 +209,6 @@ class BrowserUseAgent(Agent):
|
|
|
275
209
|
self.token_cost_service = TokenCost(include_cost=calculate_cost)
|
|
276
210
|
self.token_cost_service.register_llm(llm)
|
|
277
211
|
self.token_cost_service.register_llm(page_extraction_llm)
|
|
278
|
-
# Note: No longer registering planner_llm (deprecated)
|
|
279
212
|
|
|
280
213
|
# Initialize state
|
|
281
214
|
self.state = injected_agent_state or AgentState()
|
|
@@ -297,8 +230,19 @@ class BrowserUseAgent(Agent):
|
|
|
297
230
|
# Action setup
|
|
298
231
|
self._setup_action_models()
|
|
299
232
|
self._set_browser_use_version_and_source(source)
|
|
300
|
-
self.initial_actions = self._convert_initial_actions(initial_actions) if initial_actions else None
|
|
301
233
|
|
|
234
|
+
initial_url = None
|
|
235
|
+
|
|
236
|
+
# only load url if no initial actions are provided
|
|
237
|
+
if self.directly_open_url and not self.state.follow_up_task and not initial_actions:
|
|
238
|
+
initial_url = self._extract_url_from_task(self.task)
|
|
239
|
+
if initial_url:
|
|
240
|
+
self.logger.info(f'🔗 Found URL in task: {initial_url}, adding as initial action...')
|
|
241
|
+
initial_actions = [{'go_to_url': {'url': initial_url, 'new_tab': False}}]
|
|
242
|
+
|
|
243
|
+
self.initial_url = initial_url
|
|
244
|
+
|
|
245
|
+
self.initial_actions = self._convert_initial_actions(initial_actions) if initial_actions else None
|
|
302
246
|
# Verify we can connect to the model
|
|
303
247
|
self._verify_and_setup_llm()
|
|
304
248
|
|
|
@@ -308,40 +252,35 @@ class BrowserUseAgent(Agent):
|
|
|
308
252
|
self.logger.warning(
|
|
309
253
|
'⚠️ DeepSeek models do not support use_vision=True yet. Setting use_vision=False for now...')
|
|
310
254
|
self.settings.use_vision = False
|
|
311
|
-
# Note: No longer checking planner_llm for DeepSeek (deprecated)
|
|
312
255
|
|
|
313
256
|
# Handle users trying to use use_vision=True with XAI models
|
|
314
257
|
if 'grok' in self.llm.model.lower():
|
|
315
258
|
self.logger.warning('⚠️ XAI models do not support use_vision=True yet. Setting use_vision=False for now...')
|
|
316
259
|
self.settings.use_vision = False
|
|
317
|
-
# Note: No longer checking planner_llm for XAI models (deprecated)
|
|
318
260
|
|
|
319
261
|
self.logger.info(f'🧠 Starting a browser-use version {self.version} with model={self.llm.model}')
|
|
320
|
-
self.logger.
|
|
262
|
+
self.logger.info(
|
|
321
263
|
f'{" +vision" if self.settings.use_vision else ""}'
|
|
322
264
|
f' extraction_model={self.settings.page_extraction_llm.model if self.settings.page_extraction_llm else "Unknown"}'
|
|
323
|
-
# Note: No longer logging planner_model (deprecated)
|
|
324
265
|
f'{" +file_system" if self.file_system else ""}'
|
|
325
266
|
)
|
|
326
267
|
|
|
327
268
|
# Initialize available actions for system prompt (only non-filtered actions)
|
|
328
269
|
# These will be used for the system prompt to maintain caching
|
|
329
|
-
self.unfiltered_actions = self.
|
|
270
|
+
self.unfiltered_actions = self.tools.registry.get_prompt_description()
|
|
330
271
|
|
|
331
272
|
# Initialize message manager with state
|
|
332
273
|
# Initial system prompt with all actions - will be updated during each step
|
|
333
|
-
|
|
274
|
+
self._message_manager = MessageManager(
|
|
275
|
+
task=task,
|
|
276
|
+
system_message=SystemPrompt(
|
|
334
277
|
action_description=self.unfiltered_actions,
|
|
335
278
|
max_actions_per_step=self.settings.max_actions_per_step,
|
|
336
279
|
override_system_message=override_system_message,
|
|
337
280
|
extend_system_message=extend_system_message,
|
|
338
281
|
use_thinking=self.settings.use_thinking,
|
|
339
282
|
flash_mode=self.settings.flash_mode,
|
|
340
|
-
).get_system_message()
|
|
341
|
-
self.logger.debug(system_message)
|
|
342
|
-
self._message_manager = MessageManager(
|
|
343
|
-
task=task,
|
|
344
|
-
system_message=system_message,
|
|
283
|
+
).get_system_message(),
|
|
345
284
|
file_system=self.file_system,
|
|
346
285
|
state=self.state.message_manager_state,
|
|
347
286
|
use_thinking=self.settings.use_thinking,
|
|
@@ -354,13 +293,6 @@ class BrowserUseAgent(Agent):
|
|
|
354
293
|
include_recent_events=self.include_recent_events,
|
|
355
294
|
)
|
|
356
295
|
|
|
357
|
-
browser_profile = browser_profile or DEFAULT_BROWSER_PROFILE
|
|
358
|
-
|
|
359
|
-
self.browser_session = browser_session or BrowserSession(
|
|
360
|
-
browser_profile=browser_profile,
|
|
361
|
-
id=uuid7str()[:-4] + self.id[-4:], # re-use the same 4-char suffix so they show up together in logs
|
|
362
|
-
)
|
|
363
|
-
|
|
364
296
|
if self.sensitive_data:
|
|
365
297
|
# Check if sensitive_data has domain-specific credentials
|
|
366
298
|
has_domain_specific_credentials = any(isinstance(v, dict) for v in self.sensitive_data.values())
|
|
@@ -430,9 +362,6 @@ class BrowserUseAgent(Agent):
|
|
|
430
362
|
self.register_done_callback = register_done_callback
|
|
431
363
|
self.register_external_agent_status_raise_error_callback = register_external_agent_status_raise_error_callback
|
|
432
364
|
|
|
433
|
-
# Context
|
|
434
|
-
self.context: Context | None = context
|
|
435
|
-
|
|
436
365
|
# Telemetry
|
|
437
366
|
self.telemetry = ProductTelemetry()
|
|
438
367
|
|
|
@@ -586,39 +515,6 @@ class BrowserUseAgent(Agent):
|
|
|
586
515
|
|
|
587
516
|
self.logger.debug('🔧 Browser session started with watchdogs attached')
|
|
588
517
|
|
|
589
|
-
# Check if task contains a URL and add it as an initial action (only if preload is enabled)
|
|
590
|
-
if self.preload:
|
|
591
|
-
initial_url = self._extract_url_from_task(self.task)
|
|
592
|
-
if initial_url:
|
|
593
|
-
self.logger.info(f'🔗 Found URL in task: {initial_url}, adding as initial action...')
|
|
594
|
-
|
|
595
|
-
# Create a go_to_url action for the initial URL
|
|
596
|
-
go_to_url_action = {
|
|
597
|
-
'go_to_url': {
|
|
598
|
-
'url': initial_url,
|
|
599
|
-
'new_tab': False, # Navigate in current tab
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
# Add to initial_actions or create new list if none exist
|
|
604
|
-
if self.initial_actions:
|
|
605
|
-
# Convert back to dict format, prepend URL navigation, then convert back
|
|
606
|
-
initial_actions_dicts = []
|
|
607
|
-
for action in self.initial_actions:
|
|
608
|
-
action_data = action.model_dump(exclude_unset=True)
|
|
609
|
-
initial_actions_dicts.append(action_data)
|
|
610
|
-
|
|
611
|
-
# Prepend the go_to_url action
|
|
612
|
-
initial_actions_dicts = [go_to_url_action] + initial_actions_dicts
|
|
613
|
-
|
|
614
|
-
# Convert back to ActionModel instances
|
|
615
|
-
self.initial_actions = self._convert_initial_actions(initial_actions_dicts)
|
|
616
|
-
else:
|
|
617
|
-
# Create new initial_actions with just the go_to_url
|
|
618
|
-
self.initial_actions = self._convert_initial_actions([go_to_url_action])
|
|
619
|
-
|
|
620
|
-
self.logger.debug(f'✅ Added navigation to {initial_url} as initial action')
|
|
621
|
-
|
|
622
518
|
# Execute initial actions if provided
|
|
623
519
|
if self.initial_actions:
|
|
624
520
|
self.logger.debug(f'⚡ Executing {len(self.initial_actions)} initial actions...')
|
|
@@ -964,14 +860,13 @@ class BrowserUseAgent(Agent):
|
|
|
964
860
|
self.logger.info(f' 🦾 {blue}[PARALLEL ACTION {action_index + 1}/{total_actions}]{reset} {action_params}')
|
|
965
861
|
|
|
966
862
|
# Execute the action
|
|
967
|
-
result = await self.
|
|
863
|
+
result = await self.tools.act(
|
|
968
864
|
action=action,
|
|
969
865
|
browser_session=self.browser_session,
|
|
970
866
|
file_system=self.file_system,
|
|
971
867
|
page_extraction_llm=self.settings.page_extraction_llm,
|
|
972
868
|
sensitive_data=self.sensitive_data,
|
|
973
869
|
available_file_paths=self.available_file_paths,
|
|
974
|
-
context=self.context,
|
|
975
870
|
)
|
|
976
871
|
|
|
977
872
|
time_end = time.time()
|
|
@@ -1086,14 +981,13 @@ class BrowserUseAgent(Agent):
|
|
|
1086
981
|
|
|
1087
982
|
self.logger.info(f' 🦾 {blue}[ACTION {action_index + 1}/{total_actions}]{reset} {action_params}')
|
|
1088
983
|
|
|
1089
|
-
result = await self.
|
|
984
|
+
result = await self.tools.act(
|
|
1090
985
|
action=action,
|
|
1091
986
|
browser_session=self.browser_session,
|
|
1092
987
|
file_system=self.file_system,
|
|
1093
988
|
page_extraction_llm=self.settings.page_extraction_llm,
|
|
1094
989
|
sensitive_data=self.sensitive_data,
|
|
1095
990
|
available_file_paths=self.available_file_paths,
|
|
1096
|
-
context=self.context,
|
|
1097
991
|
)
|
|
1098
992
|
|
|
1099
993
|
time_end = time.time()
|
|
@@ -30,7 +30,7 @@ from vibe_surf.agents.prompts.vibe_surf_prompt import (
|
|
|
30
30
|
SUPERVISOR_AGENT_SYSTEM_PROMPT,
|
|
31
31
|
)
|
|
32
32
|
from vibe_surf.browser.browser_manager import BrowserManager
|
|
33
|
-
from vibe_surf.controller.
|
|
33
|
+
from vibe_surf.controller.vibesurf_tools import VibeSurfController
|
|
34
34
|
|
|
35
35
|
logger = logging.getLogger(__name__)
|
|
36
36
|
|
|
@@ -798,7 +798,6 @@ async def execute_parallel_browser_tasks(state: VibeSurfState) -> List[BrowserTa
|
|
|
798
798
|
file_system_path=state.task_dir,
|
|
799
799
|
register_new_step_callback=step_callback,
|
|
800
800
|
extend_system_message="Please make sure the language of your output in JSON value should remain the same as the user's request or task.",
|
|
801
|
-
preload=False
|
|
802
801
|
)
|
|
803
802
|
agents.append(agent)
|
|
804
803
|
|
|
@@ -896,7 +895,6 @@ async def execute_single_browser_tasks(state: VibeSurfState) -> List[BrowserTask
|
|
|
896
895
|
task_id=f"{state.task_id}-{i}",
|
|
897
896
|
file_system_path=state.task_dir,
|
|
898
897
|
register_new_step_callback=step_callback,
|
|
899
|
-
preload=False,
|
|
900
898
|
extend_system_message="Please make sure the language of your output in JSON values should remain the same as the user's request or task."
|
|
901
899
|
)
|
|
902
900
|
|
|
@@ -1502,11 +1500,14 @@ class VibeSurfAgent:
|
|
|
1502
1500
|
if upload_files and not isinstance(upload_files, list):
|
|
1503
1501
|
upload_files = [upload_files]
|
|
1504
1502
|
upload_files_md = format_upload_files_list(upload_files)
|
|
1503
|
+
user_request = f"* User's New Request:\n{task}\n"
|
|
1504
|
+
if upload_files:
|
|
1505
|
+
user_request += f"* User Uploaded Files:\n{upload_files_md}\n"
|
|
1505
1506
|
supervisor_message_history.append(
|
|
1506
1507
|
UserMessage(
|
|
1507
|
-
content=
|
|
1508
|
+
content=user_request)
|
|
1508
1509
|
)
|
|
1509
|
-
logger.info(
|
|
1510
|
+
logger.info(user_request)
|
|
1510
1511
|
|
|
1511
1512
|
if self.cur_session_id not in self.activity_logs:
|
|
1512
1513
|
self.activity_logs[self.cur_session_id] = []
|
|
@@ -1604,7 +1605,7 @@ class VibeSurfAgent:
|
|
|
1604
1605
|
if session_id is None:
|
|
1605
1606
|
session_id = self.cur_session_id
|
|
1606
1607
|
|
|
1607
|
-
logger.
|
|
1608
|
+
logger.debug(f"📊 GET_ACTIVITY_LOGS DEBUG - Session: {session_id}, Message Index: {message_index}, Current Session: {self.cur_session_id}")
|
|
1608
1609
|
|
|
1609
1610
|
# Ensure session_id exists in activity_logs
|
|
1610
1611
|
if session_id not in self.activity_logs:
|
|
@@ -1612,10 +1613,10 @@ class VibeSurfAgent:
|
|
|
1612
1613
|
return None
|
|
1613
1614
|
|
|
1614
1615
|
session_logs = self.activity_logs[session_id]
|
|
1615
|
-
logger.
|
|
1616
|
+
logger.debug(f"📋 Session {session_id} has {len(session_logs)} activity logs")
|
|
1616
1617
|
|
|
1617
1618
|
if message_index is None:
|
|
1618
|
-
logger.
|
|
1619
|
+
logger.debug(f"📤 Returning all {len(session_logs)} activity logs for session {session_id}")
|
|
1619
1620
|
return session_logs
|
|
1620
1621
|
else:
|
|
1621
1622
|
if message_index >= len(session_logs):
|
|
@@ -1623,7 +1624,7 @@ class VibeSurfAgent:
|
|
|
1623
1624
|
return None
|
|
1624
1625
|
else:
|
|
1625
1626
|
activity_log = session_logs[message_index]
|
|
1626
|
-
logger.
|
|
1627
|
+
logger.debug(f"📤 Returning activity log at index {message_index}: {activity_log.get('agent_name', 'unknown')} - {activity_log.get('agent_status', 'unknown')}")
|
|
1627
1628
|
return activity_log
|
|
1628
1629
|
|
|
1629
1630
|
async def _get_result(self, state) -> str:
|
|
@@ -15,7 +15,7 @@ from pathlib import Path
|
|
|
15
15
|
|
|
16
16
|
# VibeSurf components
|
|
17
17
|
from vibe_surf.agents.vibe_surf_agent import VibeSurfAgent
|
|
18
|
-
from vibe_surf.controller.
|
|
18
|
+
from vibe_surf.controller.vibesurf_tools import VibeSurfController
|
|
19
19
|
from vibe_surf.browser.browser_manager import BrowserManager
|
|
20
20
|
from browser_use.llm.base import BaseChatModel
|
|
21
21
|
from browser_use.llm.openai.chat import ChatOpenAI
|
|
@@ -5,47 +5,17 @@ Uses machine MAC address for key derivation to encrypt sensitive data like API k
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import hashlib
|
|
8
|
+
import pdb
|
|
8
9
|
import uuid
|
|
9
10
|
import base64
|
|
10
11
|
from cryptography.fernet import Fernet
|
|
11
12
|
from cryptography.hazmat.primitives import hashes
|
|
12
13
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
14
|
+
from getmac import get_mac_address
|
|
16
15
|
|
|
17
|
-
import psutil
|
|
18
16
|
import logging
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
def get_machine_id() -> str:
|
|
22
|
-
"""Get unique machine identifier based on MAC address."""
|
|
23
|
-
try:
|
|
24
|
-
nics = psutil.net_if_addrs()
|
|
25
|
-
|
|
26
|
-
priority_interfaces = ['en0', 'eth0', 'en1']
|
|
27
|
-
|
|
28
|
-
for interface in priority_interfaces:
|
|
29
|
-
if interface in nics:
|
|
30
|
-
for addr in nics[interface]:
|
|
31
|
-
if addr.family == psutil.AF_LINK:
|
|
32
|
-
mac = addr.address
|
|
33
|
-
if mac and mac != '00:00:00:00:00:00':
|
|
34
|
-
return mac.replace(':', '').upper()
|
|
35
|
-
|
|
36
|
-
for interface, addrs in nics.items():
|
|
37
|
-
for addr in addrs:
|
|
38
|
-
if addr.family == psutil.AF_LINK:
|
|
39
|
-
mac = addr.address
|
|
40
|
-
if (mac and mac != '00:00:00:00:00:00' and
|
|
41
|
-
not mac.startswith('02:') and
|
|
42
|
-
not interface.startswith(('lo', 'docker', 'veth'))):
|
|
43
|
-
return mac.replace(':', '').upper()
|
|
44
|
-
|
|
45
|
-
except Exception as e:
|
|
46
|
-
logging.warning(f"Could not get MAC address via psutil: {e}")
|
|
47
|
-
|
|
48
|
-
return "VIBESURF_WARMSHAO"
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
49
19
|
|
|
50
20
|
|
|
51
21
|
def derive_key(machine_id: str, salt: bytes = None) -> bytes:
|
|
@@ -69,8 +39,8 @@ def derive_key(machine_id: str, salt: bytes = None) -> bytes:
|
|
|
69
39
|
|
|
70
40
|
def get_encryption_key() -> bytes:
|
|
71
41
|
"""Get the encryption key for this machine."""
|
|
72
|
-
|
|
73
|
-
return derive_key(
|
|
42
|
+
machine_id1 = get_mac_address()
|
|
43
|
+
return derive_key(machine_id1)
|
|
74
44
|
|
|
75
45
|
def encrypt_api_key(api_key: str) -> str:
|
|
76
46
|
"""
|
|
@@ -20,8 +20,8 @@ from browser_use.browser import BrowserProfile
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class AgentBrowserProfile(BrowserProfile):
|
|
23
|
-
custom_extensions: list = Field(
|
|
24
|
-
default=
|
|
23
|
+
custom_extensions: list[str] | None = Field(
|
|
24
|
+
default=None,
|
|
25
25
|
description="Enable Custom Extensions.",
|
|
26
26
|
)
|
|
27
27
|
|
|
@@ -121,10 +121,9 @@ class AgentBrowserProfile(BrowserProfile):
|
|
|
121
121
|
'--enable-extension-activity-logging',
|
|
122
122
|
'--disable-features=DisableLoadExtensionCommandLineSwitch'
|
|
123
123
|
]
|
|
124
|
-
|
|
125
124
|
if self.custom_extensions:
|
|
126
125
|
extension_paths.extend(self.custom_extensions)
|
|
127
126
|
if extension_paths:
|
|
128
127
|
args.append(f'--load-extension={",".join(extension_paths)}')
|
|
129
|
-
|
|
128
|
+
logger.info(f"Extension infos: {args}")
|
|
130
129
|
return args
|