Skip to content

Commit a25df05

Browse files
committed
adapt webui
1 parent 45168a3 commit a25df05

File tree

7 files changed

+247
-252
lines changed

7 files changed

+247
-252
lines changed

.env.example

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ MOONSHOT_ENDPOINT=https://api.moonshot.cn/v1
2525
MOONSHOT_API_KEY=
2626

2727
# Set to false to disable anonymized telemetry
28-
ANONYMIZED_TELEMETRY=true
28+
ANONYMIZED_TELEMETRY=false
2929

3030
# LogLevel: Set to debug to enable verbose logging, set to result to get results only. Available: result | debug | info
3131
BROWSER_USE_LOGGING_LEVEL=info

src/agent/custom_agent.py

-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ def __init__(
163163
)
164164
self.state = injected_agent_state or CustomAgentState()
165165
self.add_infos = add_infos
166-
167166
self._message_manager = CustomMessageManager(
168167
task=task,
169168
system_message=self.settings.system_prompt_class(

src/agent/custom_prompts.py

+9-90
Original file line numberDiff line numberDiff line change
@@ -6,101 +6,20 @@
66
from browser_use.browser.views import BrowserState
77
from langchain_core.messages import HumanMessage, SystemMessage
88
from datetime import datetime
9+
import importlib
910

1011
from .custom_views import CustomAgentStepInfo
1112

1213

1314
class CustomSystemPrompt(SystemPrompt):
14-
def important_rules(self) -> str:
15-
"""
16-
Returns the important rules for the agent.
17-
"""
18-
text = r"""
19-
1. RESPONSE FORMAT: You must ALWAYS respond with valid JSON in this exact format:
20-
{
21-
"current_state": {
22-
"evaluation_previous_goal": "Success|Failed|Unknown - Analyze the current elements and the image to check if the previous goals/actions are successful like intended by the task. Mention if something unexpected happened. Shortly state why/why not.",
23-
"important_contents": "Output important contents closely related to user's instruction on the current page. If there is, please output the contents. If not, please output ''.",
24-
"thought": "Think about the requirements that have been completed in previous operations and the requirements that need to be completed in the next one operation. If your output of evaluation_previous_goal is 'Failed', please reflect and output your reflection here.",
25-
"next_goal": "Please generate a brief natural language description for the goal of your next actions based on your thought."
26-
},
27-
"action": [
28-
* actions in sequences, please refer to **Common action sequences**. Each output action MUST be formated as: \{action_name\: action_params\}*
29-
]
30-
}
31-
32-
2. ACTIONS: You can specify multiple actions to be executed in sequence.
33-
34-
Common action sequences:
35-
- Form filling: [
36-
{"input_text": {"index": 1, "text": "username"}},
37-
{"input_text": {"index": 2, "text": "password"}},
38-
{"click_element": {"index": 3}}
39-
]
40-
- Navigation and extraction: [
41-
{"go_to_url": {"url": "https://example.com"}},
42-
{"extract_page_content": {"goal": "extract the names"}}
43-
]
44-
45-
46-
3. ELEMENT INTERACTION:
47-
- Only use indexes that exist in the provided element list
48-
- Elements marked with "[]Non-interactive text" are non-interactive
49-
50-
4. NAVIGATION & ERROR HANDLING:
51-
- If no suitable elements exist, use other functions to complete the task
52-
- If stuck, try alternative approaches
53-
- Handle popups/cookies by accepting or closing them
54-
- Use scroll to find elements you are looking for
55-
56-
5. TASK COMPLETION:
57-
- Use the done action as the last action as soon as the ultimate task is complete
58-
- Dont use "done" before you are done with everything the user asked you, except you reach the last step of max_steps.
59-
- If you reach your last step, use the done action even if the task is not fully finished. Provide all the information you have gathered so far. If the ultimate task is completly finished set success to true. If not everything the user asked for is completed set success in done to false!
60-
- If you have to do something repeatedly for example the task says for "each", or "for all", or "x times", count always inside "memory" how many times you have done it and how many remain. Don't stop until you have completed like the task asked you. Only call done after the last step.
61-
- Don't hallucinate actions
62-
- Make sure you include everything you found out for the ultimate task in the done text parameter. Do not just say you are done, but include the requested information of the task.
63-
64-
6. VISUAL CONTEXT:
65-
- When an image is provided, use it to understand the page layout
66-
- Bounding boxes with labels on their top right corner correspond to element indexes
67-
68-
7. Form filling:
69-
- If you fill an input field and your action sequence is interrupted, most often something changed e.g. suggestions popped up under the field.
70-
71-
8. Long tasks:
72-
- Keep track of the status and subresults in the memory.
73-
74-
9. Extraction:
75-
- If your task is to find information - call extract_content on the specific pages to get and store the information.
76-
77-
"""
78-
text += f" - use maximum {self.max_actions_per_step} actions per sequence"
79-
return text
80-
81-
def input_format(self) -> str:
82-
return """
83-
INPUT STRUCTURE:
84-
1. Task: The user\'s instructions you need to complete.
85-
2. Hints(Optional): Some hints to help you complete the user\'s instructions.
86-
3. Memory: Important contents are recorded during historical operations for use in subsequent operations.
87-
4. Current URL: The webpage you're currently on
88-
5. Available Tabs: List of open browser tabs
89-
6. Interactive Elements: List in the format:
90-
[index]<element_type>element_text</element_type>
91-
- index: Numeric identifier for interaction
92-
- element_type: HTML element type (button, input, etc.)
93-
- element_text: Visible text or element description
94-
95-
Example:
96-
[33]<button>Submit Form</button>
97-
[] Non-interactive text
98-
99-
100-
Notes:
101-
- Only elements with numeric indexes inside [] are interactive
102-
- [] elements provide context but cannot be interacted with
103-
"""
15+
def _load_prompt_template(self) -> None:
16+
"""Load the prompt template from the markdown file."""
17+
try:
18+
# This works both in development and when installed as a package
19+
with importlib.resources.files('src.agent').joinpath('custom_system_prompt.md').open('r') as f:
20+
self.prompt_template = f.read()
21+
except Exception as e:
22+
raise RuntimeError(f'Failed to load system prompt template: {e}')
10423

10524

10625
class CustomAgentMessagePrompt(AgentMessagePrompt):

src/agent/custom_system_prompt.md

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
You are an AI agent designed to automate browser tasks. Your goal is to accomplish the ultimate task following the rules.
2+
3+
# Input Format
4+
Task
5+
Previous steps
6+
Current URL
7+
Open Tabs
8+
Interactive Elements
9+
[index]<type>text</type>
10+
- index: Numeric identifier for interaction
11+
- type: HTML element type (button, input, etc.)
12+
- text: Element description
13+
Example:
14+
[33]<button>Submit Form</button>
15+
16+
- Only elements with numeric indexes in [] are interactive
17+
- elements without [] provide only context
18+
19+
# Response Rules
20+
1. RESPONSE FORMAT: You must ALWAYS respond with valid JSON in this exact format:
21+
{{"current_state": {{"evaluation_previous_goal": "Success|Failed|Unknown - Analyze the current elements and the image to check if the previous goals/actions are successful like intended by the task. Mention if something unexpected happened. Shortly state why/why not.",
22+
"important_contents": "Output important contents closely related to user's instruction on the current page. If there is, please output the contents. If not, please output ''.",
23+
"thought": "Think about the requirements that have been completed in previous operations and the requirements that need to be completed in the next one operation. If your output of evaluation_previous_goal is 'Failed', please reflect and output your reflection here.",
24+
"next_goal": "Please generate a brief natural language description for the goal of your next actions based on your thought."}},
25+
"action":[{{"one_action_name": {{// action-specific parameter}}}}, // ... more actions in sequence]}}
26+
27+
2. ACTIONS: You can specify multiple actions in the list to be executed in sequence. But always specify only one action name per item. Use maximum {{max_actions}} actions per sequence.
28+
Common action sequences:
29+
- Form filling: [{{"input_text": {{"index": 1, "text": "username"}}}}, {{"input_text": {{"index": 2, "text": "password"}}}}, {{"click_element": {{"index": 3}}}}]
30+
- Navigation and extraction: [{{"go_to_url": {{"url": "https://example.com"}}}}, {{"extract_content": {{"goal": "extract the names"}}}}]
31+
- Actions are executed in the given order
32+
- If the page changes after an action, the sequence is interrupted and you get the new state.
33+
- Only provide the action sequence until an action which changes the page state significantly.
34+
- Try to be efficient, e.g. fill forms at once, or chain actions where nothing changes on the page
35+
- only use multiple actions if it makes sense.
36+
37+
3. ELEMENT INTERACTION:
38+
- Only use indexes of the interactive elements
39+
- Elements marked with "[]Non-interactive text" are non-interactive
40+
41+
4. NAVIGATION & ERROR HANDLING:
42+
- If no suitable elements exist, use other functions to complete the task
43+
- If stuck, try alternative approaches - like going back to a previous page, new search, new tab etc.
44+
- Handle popups/cookies by accepting or closing them
45+
- Use scroll to find elements you are looking for
46+
- If you want to research something, open a new tab instead of using the current tab
47+
- If captcha pops up, try to solve it - else try a different approach
48+
- If the page is not fully loaded, use wait action
49+
50+
5. TASK COMPLETION:
51+
- Use the done action as the last action as soon as the ultimate task is complete
52+
- Dont use "done" before you are done with everything the user asked you, except you reach the last step of max_steps.
53+
- If you reach your last step, use the done action even if the task is not fully finished. Provide all the information you have gathered so far. If the ultimate task is completly finished set success to true. If not everything the user asked for is completed set success in done to false!
54+
- If you have to do something repeatedly for example the task says for "each", or "for all", or "x times", count always inside "memory" how many times you have done it and how many remain. Don't stop until you have completed like the task asked you. Only call done after the last step.
55+
- Don't hallucinate actions
56+
- Make sure you include everything you found out for the ultimate task in the done text parameter. Do not just say you are done, but include the requested information of the task.
57+
58+
6. VISUAL CONTEXT:
59+
- When an image is provided, use it to understand the page layout
60+
- Bounding boxes with labels on their top right corner correspond to element indexes
61+
62+
7. Form filling:
63+
- If you fill an input field and your action sequence is interrupted, most often something changed e.g. suggestions popped up under the field.
64+
65+
8. Long tasks:
66+
- Keep track of the status and subresults in the memory.
67+
68+
9. Extraction:
69+
- If your task is to find information - call extract_content on the specific pages to get and store the information.
70+
Your responses must be always JSON with the specified format.

src/utils/deep_research.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async def deep_research(task, llm, agent_state=None, **kwargs):
4444

4545
use_own_browser = kwargs.get("use_own_browser", False)
4646
extra_chromium_args = []
47-
cdp_url = kwargs.get("chrome_cdp", None)
47+
4848
if use_own_browser:
4949
cdp_url = os.getenv("CHROME_CDP", kwargs.get("chrome_cdp", None))
5050
# TODO: if use own browser, max query num must be 1 per iter, how to solve it?

tests/test_browser_use.py

+27-16
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,21 @@ async def test_browser_use_custom():
118118
# api_key=os.getenv("OPENAI_API_KEY", ""),
119119
# )
120120

121-
llm = utils.get_llm_model(
122-
provider="azure_openai",
123-
model_name="gpt-4o",
124-
temperature=0.8,
125-
base_url=os.getenv("AZURE_OPENAI_ENDPOINT", ""),
126-
api_key=os.getenv("AZURE_OPENAI_API_KEY", ""),
127-
)
128-
129121
# llm = utils.get_llm_model(
130-
# provider="google",
131-
# model_name="gemini-2.0-flash",
132-
# temperature=1.0,
133-
# api_key=os.getenv("GOOGLE_API_KEY", "")
122+
# provider="azure_openai",
123+
# model_name="gpt-4o",
124+
# temperature=0.6,
125+
# base_url=os.getenv("AZURE_OPENAI_ENDPOINT", ""),
126+
# api_key=os.getenv("AZURE_OPENAI_API_KEY", ""),
134127
# )
135128

129+
llm = utils.get_llm_model(
130+
provider="google",
131+
model_name="gemini-2.0-flash",
132+
temperature=0.6,
133+
api_key=os.getenv("GOOGLE_API_KEY", "")
134+
)
135+
136136
# llm = utils.get_llm_model(
137137
# provider="deepseek",
138138
# model_name="deepseek-reasoner",
@@ -193,7 +193,7 @@ async def test_browser_use_custom():
193193
)
194194
)
195195
agent = CustomAgent(
196-
task="Give me stock price of Tesla",
196+
task="Give me stock price of Nvidia",
197197
add_infos="", # some hints for llm to complete the task
198198
llm=llm,
199199
browser=browser,
@@ -202,13 +202,25 @@ async def test_browser_use_custom():
202202
system_prompt_class=CustomSystemPrompt,
203203
agent_prompt_class=CustomAgentMessagePrompt,
204204
use_vision=use_vision,
205-
max_actions_per_step=max_actions_per_step
205+
max_actions_per_step=max_actions_per_step,
206+
generate_gif=True
206207
)
207208
history: AgentHistoryList = await agent.run(max_steps=100)
208209

209210
print("Final Result:")
210211
pprint(history.final_result(), indent=4)
211212

213+
print("\nErrors:")
214+
pprint(history.errors(), indent=4)
215+
216+
# e.g. xPaths the model clicked on
217+
print("\nModel Outputs:")
218+
pprint(history.model_actions(), indent=4)
219+
220+
print("\nThoughts:")
221+
pprint(history.model_thoughts(), indent=4)
222+
223+
212224
except Exception:
213225
import traceback
214226

@@ -305,9 +317,8 @@ async def test_browser_use_parallel():
305317
for task in [
306318
'Search Google for weather in Tokyo',
307319
'Check Reddit front page title',
308-
'大S去世',
309320
'Find NASA image of the day',
310-
# 'Check top story on CNN',
321+
'Check top story on CNN',
311322
# 'Search latest SpaceX launch date',
312323
# 'Look up population of Paris',
313324
# 'Find current time in Sydney',

0 commit comments

Comments
 (0)