8
8
import base64
9
9
import io
10
10
import platform
11
- from browser_use .agent .prompts import SystemPrompt
11
+ from browser_use .agent .prompts import SystemPrompt , AgentMessagePrompt
12
12
from browser_use .agent .service import Agent
13
13
from browser_use .agent .views import (
14
14
ActionResult ,
15
+ ActionModel ,
15
16
AgentHistoryList ,
16
17
AgentOutput ,
17
18
AgentHistory ,
30
31
from langchain_core .messages import (
31
32
BaseMessage ,
32
33
)
34
+ from json_repair import repair_json
33
35
from src .utils .agent_state import AgentState
34
36
35
37
from .custom_massage_manager import CustomMassageManager
@@ -52,6 +54,7 @@ def __init__(
52
54
max_failures : int = 5 ,
53
55
retry_delay : int = 10 ,
54
56
system_prompt_class : Type [SystemPrompt ] = SystemPrompt ,
57
+ agent_prompt_class : Type [AgentMessagePrompt ] = AgentMessagePrompt ,
55
58
max_input_tokens : int = 128000 ,
56
59
validate_output : bool = False ,
57
60
include_attributes : list [str ] = [
@@ -98,28 +101,31 @@ def __init__(
98
101
register_done_callback = register_done_callback ,
99
102
tool_calling_method = tool_calling_method
100
103
)
101
- if self .model_name in ["deepseek-reasoner" ] or self . model_name . startswith ( "deepseek-r1" ) :
104
+ if self .model_name in ["deepseek-reasoner" ] or "deepseek-r1" in self . model_name :
102
105
# deepseek-reasoner does not support function calling
103
106
self .use_deepseek_r1 = True
104
107
# deepseek-reasoner only support 64000 context
105
108
self .max_input_tokens = 64000
106
109
else :
107
110
self .use_deepseek_r1 = False
108
111
112
+ # record last actions
113
+ self ._last_actions = None
109
114
# custom new info
110
115
self .add_infos = add_infos
111
116
# agent_state for Stop
112
117
self .agent_state = agent_state
118
+ self .agent_prompt_class = agent_prompt_class
113
119
self .message_manager = CustomMassageManager (
114
120
llm = self .llm ,
115
121
task = self .task ,
116
122
action_descriptions = self .controller .registry .get_prompt_description (),
117
123
system_prompt_class = self .system_prompt_class ,
124
+ agent_prompt_class = agent_prompt_class ,
118
125
max_input_tokens = self .max_input_tokens ,
119
126
include_attributes = self .include_attributes ,
120
127
max_error_length = self .max_error_length ,
121
- max_actions_per_step = self .max_actions_per_step ,
122
- use_deepseek_r1 = self .use_deepseek_r1
128
+ max_actions_per_step = self .max_actions_per_step
123
129
)
124
130
125
131
def _setup_action_models (self ) -> None :
@@ -186,9 +192,11 @@ async def get_next_action(self, input_messages: list[BaseMessage]) -> AgentOutpu
186
192
logger .info (ai_message .reasoning_content )
187
193
logger .info (f"🤯 End Deep Thinking" )
188
194
if isinstance (ai_message .content , list ):
189
- parsed_json = json . loads ( ai_message .content [0 ].replace ("```json" , "" ).replace ("```" , "" ) )
195
+ ai_content = ai_message .content [0 ].replace ("```json" , "" ).replace ("```" , "" )
190
196
else :
191
- parsed_json = json .loads (ai_message .content .replace ("```json" , "" ).replace ("```" , "" ))
197
+ ai_content = ai_message .content .replace ("```json" , "" ).replace ("```" , "" )
198
+ ai_content = repair_json (ai_content )
199
+ parsed_json = json .loads (ai_content )
192
200
parsed : AgentOutput = self .AgentOutput (** parsed_json )
193
201
if parsed is None :
194
202
logger .debug (ai_message .content )
@@ -197,9 +205,11 @@ async def get_next_action(self, input_messages: list[BaseMessage]) -> AgentOutpu
197
205
ai_message = self .llm .invoke (input_messages )
198
206
self .message_manager ._add_message_with_tokens (ai_message )
199
207
if isinstance (ai_message .content , list ):
200
- parsed_json = json . loads ( ai_message .content [0 ].replace ("```json" , "" ).replace ("```" , "" ) )
208
+ ai_content = ai_message .content [0 ].replace ("```json" , "" ).replace ("```" , "" )
201
209
else :
202
- parsed_json = json .loads (ai_message .content .replace ("```json" , "" ).replace ("```" , "" ))
210
+ ai_content = ai_message .content .replace ("```json" , "" ).replace ("```" , "" )
211
+ ai_content = repair_json (ai_content )
212
+ parsed_json = json .loads (ai_content )
203
213
parsed : AgentOutput = self .AgentOutput (** parsed_json )
204
214
if parsed is None :
205
215
logger .debug (ai_message .content )
@@ -222,7 +232,7 @@ async def step(self, step_info: Optional[CustomAgentStepInfo] = None) -> None:
222
232
223
233
try :
224
234
state = await self .browser_context .get_state (use_vision = self .use_vision )
225
- self .message_manager .add_state_message (state , self ._last_result , step_info )
235
+ self .message_manager .add_state_message (state , self ._last_actions , self . _last_result , step_info )
226
236
input_messages = self .message_manager .get_messages ()
227
237
try :
228
238
model_output = await self .get_next_action (input_messages )
@@ -231,8 +241,8 @@ async def step(self, step_info: Optional[CustomAgentStepInfo] = None) -> None:
231
241
self .update_step_info (model_output , step_info )
232
242
logger .info (f"🧠 All Memory: \n { step_info .memory } " )
233
243
self ._save_conversation (input_messages , model_output )
234
- # should we remove last state message? at least, deepseek-reasoner cannot remove
235
244
if self .model_name != "deepseek-reasoner" :
245
+ # remove pre-prev message
236
246
self .message_manager ._remove_last_state_message ()
237
247
except Exception as e :
238
248
# model call failed, remove last state message from history
@@ -242,16 +252,17 @@ async def step(self, step_info: Optional[CustomAgentStepInfo] = None) -> None:
242
252
result : list [ActionResult ] = await self .controller .multi_act (
243
253
model_output .action , self .browser_context
244
254
)
245
- if len (result ) != len (model_output .action ):
255
+ actions : list [ActionModel ] = model_output .action
256
+ if len (result ) != len (actions ):
246
257
# I think something changes, such information should let LLM know
247
- for ri in range (len (result ), len (model_output . action )):
258
+ for ri in range (len (result ), len (actions )):
248
259
result .append (ActionResult (extracted_content = None ,
249
260
include_in_memory = True ,
250
- error = f"{ model_output . action [ri ].model_dump_json (exclude_unset = True )} is Failed to execute. \
251
- Something new appeared after action { model_output . action [len (result ) - 1 ].model_dump_json (exclude_unset = True )} " ,
261
+ error = f"{ actions [ri ].model_dump_json (exclude_unset = True )} is Failed to execute. \
262
+ Something new appeared after action { actions [len (result ) - 1 ].model_dump_json (exclude_unset = True )} " ,
252
263
is_done = False ))
253
264
self ._last_result = result
254
-
265
+ self . _last_actions = actions
255
266
if len (result ) > 0 and result [- 1 ].is_done :
256
267
logger .info (f"📄 Result: { result [- 1 ].extracted_content } " )
257
268
0 commit comments