1
1
from __future__ import annotations
2
2
3
3
import asyncio
4
- import gc
5
- import inspect
6
- import json
7
4
import logging
8
5
import os
9
- import re
10
- import time
11
- from pathlib import Path
12
- from typing import Any , Awaitable , Callable , Dict , Generic , List , Optional , TypeVar , Union
13
-
14
- from dotenv import load_dotenv
15
- from langchain_core .language_models .chat_models import BaseChatModel
16
- from langchain_core .messages import (
17
- BaseMessage ,
18
- HumanMessage ,
19
- SystemMessage ,
20
- )
21
6
22
7
# from lmnr.sdk.decorators import observe
23
- from pydantic import BaseModel , ValidationError
24
-
25
8
from browser_use .agent .gif import create_history_gif
26
- from browser_use .agent .memory .service import Memory , MemorySettings
27
- from browser_use .agent .message_manager .service import MessageManager , MessageManagerSettings
28
- from browser_use .agent .message_manager .utils import convert_input_messages , extract_json_from_model_output , save_conversation
29
- from browser_use .agent .prompts import AgentMessagePrompt , PlannerPrompt , SystemPrompt
9
+ from browser_use .agent .service import Agent , AgentHookFunc
30
10
from browser_use .agent .views import (
31
- REQUIRED_LLM_API_ENV_VARS ,
32
- ActionResult ,
33
- AgentError ,
34
- AgentHistory ,
35
- AgentHistoryList ,
36
- AgentOutput ,
37
- AgentSettings ,
38
- AgentState ,
39
- AgentStepInfo ,
40
- StepMetadata ,
41
- ToolCallingMethod ,
42
- )
43
- from browser_use .browser .browser import Browser
44
- from browser_use .browser .context import BrowserContext
45
- from browser_use .browser .views import BrowserState , BrowserStateHistory
46
- from browser_use .controller .registry .views import ActionModel
47
- from browser_use .controller .service import Controller
48
- from browser_use .dom .history_tree_processor .service import (
49
- DOMHistoryElement ,
50
- HistoryTreeProcessor ,
11
+ AgentHistoryList ,
12
+ AgentStepInfo ,
51
13
)
52
- from browser_use .exceptions import LLMException
53
- from browser_use .telemetry .service import ProductTelemetry
54
14
from browser_use .telemetry .views import (
55
- AgentEndTelemetryEvent ,
56
- AgentRunTelemetryEvent ,
57
- AgentStepTelemetryEvent ,
15
+ AgentEndTelemetryEvent ,
58
16
)
59
- from browser_use .utils import check_env_variables , time_execution_async , time_execution_sync
60
- from browser_use . agent . service import Agent , AgentHookFunc
17
+ from browser_use .utils import time_execution_async
18
+ from dotenv import load_dotenv
61
19
62
20
load_dotenv ()
63
21
logger = logging .getLogger (__name__ )
64
22
65
- SKIP_LLM_API_KEY_VERIFICATION = os .environ .get ('SKIP_LLM_API_KEY_VERIFICATION' , 'false' ).lower ()[0 ] in 'ty1'
23
+ SKIP_LLM_API_KEY_VERIFICATION = (
24
+ os .environ .get ("SKIP_LLM_API_KEY_VERIFICATION" , "false" ).lower ()[0 ] in "ty1"
25
+ )
66
26
67
27
68
28
class BrowserUseAgent (Agent ):
69
- @time_execution_async (' --run (agent)' )
29
+ @time_execution_async (" --run (agent)" )
70
30
async def run (
71
- self , max_steps : int = 100 , on_step_start : AgentHookFunc | None = None ,
72
- on_step_end : AgentHookFunc | None = None
31
+ self ,
32
+ max_steps : int = 100 ,
33
+ on_step_start : AgentHookFunc | None = None ,
34
+ on_step_end : AgentHookFunc | None = None ,
73
35
) -> AgentHistoryList :
74
36
"""Execute the task with maximum number of steps"""
75
37
@@ -88,7 +50,7 @@ async def run(
88
50
signal_handler .register ()
89
51
90
52
# Wait for verification task to complete if it exists
91
- if hasattr (self , ' _verification_task' ) and not self ._verification_task .done ():
53
+ if hasattr (self , " _verification_task" ) and not self ._verification_task .done ():
92
54
try :
93
55
await self ._verification_task
94
56
except Exception :
@@ -100,7 +62,9 @@ async def run(
100
62
101
63
# Execute initial actions if provided
102
64
if self .initial_actions :
103
- result = await self .multi_act (self .initial_actions , check_for_new_elements = False )
65
+ result = await self .multi_act (
66
+ self .initial_actions , check_for_new_elements = False
67
+ )
104
68
self .state .last_result = result
105
69
106
70
for step in range (max_steps ):
@@ -112,12 +76,14 @@ async def run(
112
76
113
77
# Check if we should stop due to too many failures
114
78
if self .state .consecutive_failures >= self .settings .max_failures :
115
- logger .error (f'❌ Stopping due to { self .settings .max_failures } consecutive failures' )
79
+ logger .error (
80
+ f"❌ Stopping due to { self .settings .max_failures } consecutive failures"
81
+ )
116
82
break
117
83
118
84
# Check control flags before each step
119
85
if self .state .stopped :
120
- logger .info (' Agent stopped' )
86
+ logger .info (" Agent stopped" )
121
87
break
122
88
123
89
while self .state .paused :
@@ -142,13 +108,15 @@ async def run(
142
108
await self .log_completion ()
143
109
break
144
110
else :
145
- logger .info (' ❌ Failed to complete task in maximum steps' )
111
+ logger .info (" ❌ Failed to complete task in maximum steps" )
146
112
147
113
return self .state .history
148
114
149
115
except KeyboardInterrupt :
150
116
# Already handled by our signal handler, but catch any direct KeyboardInterrupt as well
151
- logger .info ('Got KeyboardInterrupt during execution, returning current history' )
117
+ logger .info (
118
+ "Got KeyboardInterrupt during execution, returning current history"
119
+ )
152
120
return self .state .history
153
121
154
122
finally :
@@ -171,8 +139,10 @@ async def run(
171
139
await self .close ()
172
140
173
141
if self .settings .generate_gif :
174
- output_path : str = ' agent_history.gif'
142
+ output_path : str = " agent_history.gif"
175
143
if isinstance (self .settings .generate_gif , str ):
176
144
output_path = self .settings .generate_gif
177
145
178
- create_history_gif (task = self .task , history = self .state .history , output_path = output_path )
146
+ create_history_gif (
147
+ task = self .task , history = self .state .history , output_path = output_path
148
+ )
0 commit comments