Skip to content

Commit 54266d8

Browse files
committed
fixed file formatting
1 parent 5539a83 commit 54266d8

File tree

10 files changed

+238
-234
lines changed

10 files changed

+238
-234
lines changed

src/agent/custom_agent.py

Lines changed: 91 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4,99 +4,85 @@
44
# @ProjectName: browser-use-webui
55
# @FileName: custom_agent.py
66

7-
import asyncio
8-
import base64
9-
import io
107
import json
118
import logging
12-
import os
13-
import pdb
14-
import textwrap
15-
import time
16-
import uuid
17-
from io import BytesIO
18-
from pathlib import Path
19-
from typing import Any, Optional, Type, TypeVar
20-
21-
from dotenv import load_dotenv
22-
from langchain_core.language_models.chat_models import BaseChatModel
23-
from langchain_core.messages import (
24-
BaseMessage,
25-
SystemMessage,
26-
)
27-
from openai import RateLimitError
28-
from PIL import Image, ImageDraw, ImageFont
29-
from pydantic import BaseModel, ValidationError
9+
from typing import Optional, Type
3010

31-
from browser_use.agent.message_manager.service import MessageManager
32-
from browser_use.agent.prompts import AgentMessagePrompt, SystemPrompt
11+
from browser_use.agent.prompts import SystemPrompt
3312
from browser_use.agent.service import Agent
3413
from browser_use.agent.views import (
3514
ActionResult,
36-
AgentError,
37-
AgentHistory,
3815
AgentHistoryList,
3916
AgentOutput,
40-
AgentStepInfo,
4117
)
4218
from browser_use.browser.browser import Browser
4319
from browser_use.browser.context import BrowserContext
44-
from browser_use.browser.views import BrowserState, BrowserStateHistory
45-
from browser_use.controller.registry.views import ActionModel
4620
from browser_use.controller.service import Controller
47-
from browser_use.dom.history_tree_processor.service import (
48-
DOMHistoryElement,
49-
HistoryTreeProcessor,
50-
)
51-
from browser_use.telemetry.service import ProductTelemetry
5221
from browser_use.telemetry.views import (
5322
AgentEndTelemetryEvent,
5423
AgentRunTelemetryEvent,
5524
AgentStepErrorTelemetryEvent,
5625
)
5726
from browser_use.utils import time_execution_async
27+
from langchain_core.language_models.chat_models import BaseChatModel
28+
from langchain_core.messages import (
29+
BaseMessage,
30+
)
5831

59-
from .custom_views import CustomAgentOutput, CustomAgentStepInfo
6032
from .custom_massage_manager import CustomMassageManager
33+
from .custom_views import CustomAgentOutput, CustomAgentStepInfo
6134

6235
logger = logging.getLogger(__name__)
6336

6437

6538
class CustomAgent(Agent):
66-
6739
def __init__(
68-
self,
69-
task: str,
70-
llm: BaseChatModel,
71-
add_infos: str = '',
72-
browser: Browser | None = None,
73-
browser_context: BrowserContext | None = None,
74-
controller: Controller = Controller(),
75-
use_vision: bool = True,
76-
save_conversation_path: Optional[str] = None,
77-
max_failures: int = 5,
78-
retry_delay: int = 10,
79-
system_prompt_class: Type[SystemPrompt] = SystemPrompt,
80-
max_input_tokens: int = 128000,
81-
validate_output: bool = False,
82-
include_attributes: list[str] = [
83-
'title',
84-
'type',
85-
'name',
86-
'role',
87-
'tabindex',
88-
'aria-label',
89-
'placeholder',
90-
'value',
91-
'alt',
92-
'aria-expanded',
93-
],
94-
max_error_length: int = 400,
95-
max_actions_per_step: int = 10,
40+
self,
41+
task: str,
42+
llm: BaseChatModel,
43+
add_infos: str = "",
44+
browser: Browser | None = None,
45+
browser_context: BrowserContext | None = None,
46+
controller: Controller = Controller(),
47+
use_vision: bool = True,
48+
save_conversation_path: Optional[str] = None,
49+
max_failures: int = 5,
50+
retry_delay: int = 10,
51+
system_prompt_class: Type[SystemPrompt] = SystemPrompt,
52+
max_input_tokens: int = 128000,
53+
validate_output: bool = False,
54+
include_attributes: list[str] = [
55+
"title",
56+
"type",
57+
"name",
58+
"role",
59+
"tabindex",
60+
"aria-label",
61+
"placeholder",
62+
"value",
63+
"alt",
64+
"aria-expanded",
65+
],
66+
max_error_length: int = 400,
67+
max_actions_per_step: int = 10,
9668
):
97-
super().__init__(task, llm, browser, browser_context, controller, use_vision, save_conversation_path,
98-
max_failures, retry_delay, system_prompt_class, max_input_tokens, validate_output,
99-
include_attributes, max_error_length, max_actions_per_step)
69+
super().__init__(
70+
task,
71+
llm,
72+
browser,
73+
browser_context,
74+
controller,
75+
use_vision,
76+
save_conversation_path,
77+
max_failures,
78+
retry_delay,
79+
system_prompt_class,
80+
max_input_tokens,
81+
validate_output,
82+
include_attributes,
83+
max_error_length,
84+
max_actions_per_step,
85+
)
10086
self.add_infos = add_infos
10187
self.message_manager = CustomMassageManager(
10288
llm=self.llm,
@@ -118,24 +104,26 @@ def _setup_action_models(self) -> None:
118104

119105
def _log_response(self, response: CustomAgentOutput) -> None:
120106
"""Log the model's response"""
121-
if 'Success' in response.current_state.prev_action_evaluation:
122-
emoji = '✅'
123-
elif 'Failed' in response.current_state.prev_action_evaluation:
124-
emoji = '❌'
107+
if "Success" in response.current_state.prev_action_evaluation:
108+
emoji = "✅"
109+
elif "Failed" in response.current_state.prev_action_evaluation:
110+
emoji = "❌"
125111
else:
126-
emoji = '🤷'
112+
emoji = "🤷"
127113

128-
logger.info(f'{emoji} Eval: {response.current_state.prev_action_evaluation}')
129-
logger.info(f'🧠 New Memory: {response.current_state.important_contents}')
130-
logger.info(f'⏳ Task Progress: {response.current_state.completed_contents}')
131-
logger.info(f'🤔 Thought: {response.current_state.thought}')
132-
logger.info(f'🎯 Summary: {response.current_state.summary}')
114+
logger.info(f"{emoji} Eval: {response.current_state.prev_action_evaluation}")
115+
logger.info(f"🧠 New Memory: {response.current_state.important_contents}")
116+
logger.info(f"⏳ Task Progress: {response.current_state.completed_contents}")
117+
logger.info(f"🤔 Thought: {response.current_state.thought}")
118+
logger.info(f"🎯 Summary: {response.current_state.summary}")
133119
for i, action in enumerate(response.action):
134120
logger.info(
135-
f'🛠️ Action {i + 1}/{len(response.action)}: {action.model_dump_json(exclude_unset=True)}'
121+
f"🛠️ Action {i + 1}/{len(response.action)}: {action.model_dump_json(exclude_unset=True)}"
136122
)
137123

138-
def update_step_info(self, model_output: CustomAgentOutput, step_info: CustomAgentStepInfo = None):
124+
def update_step_info(
125+
self, model_output: CustomAgentOutput, step_info: CustomAgentStepInfo = None
126+
):
139127
"""
140128
update step info
141129
"""
@@ -144,19 +132,23 @@ def update_step_info(self, model_output: CustomAgentOutput, step_info: CustomAge
144132

145133
step_info.step_number += 1
146134
important_contents = model_output.current_state.important_contents
147-
if important_contents and 'None' not in important_contents and important_contents not in step_info.memory:
148-
step_info.memory += important_contents + '\n'
135+
if (
136+
important_contents
137+
and "None" not in important_contents
138+
and important_contents not in step_info.memory
139+
):
140+
step_info.memory += important_contents + "\n"
149141

150142
completed_contents = model_output.current_state.completed_contents
151-
if completed_contents and 'None' not in completed_contents:
143+
if completed_contents and "None" not in completed_contents:
152144
step_info.task_progress = completed_contents
153145

154-
@time_execution_async('--get_next_action')
146+
@time_execution_async("--get_next_action")
155147
async def get_next_action(self, input_messages: list[BaseMessage]) -> AgentOutput:
156148
"""Get next action from LLM based on current state"""
157149

158150
ret = self.llm.invoke(input_messages)
159-
parsed_json = json.loads(ret.content.replace('```json', '').replace("```", ""))
151+
parsed_json = json.loads(ret.content.replace("```json", "").replace("```", ""))
160152
parsed: AgentOutput = self.AgentOutput(**parsed_json)
161153
# cut the number of actions to max_actions_per_step
162154
parsed.action = parsed.action[: self.max_actions_per_step]
@@ -165,10 +157,10 @@ async def get_next_action(self, input_messages: list[BaseMessage]) -> AgentOutpu
165157

166158
return parsed
167159

168-
@time_execution_async('--step')
160+
@time_execution_async("--step")
169161
async def step(self, step_info: Optional[CustomAgentStepInfo] = None) -> None:
170162
"""Execute one step of the task"""
171-
logger.info(f'\n📍 Step {self.n_steps}')
163+
logger.info(f"\n📍 Step {self.n_steps}")
172164
state = None
173165
model_output = None
174166
result: list[ActionResult] = []
@@ -179,7 +171,7 @@ async def step(self, step_info: Optional[CustomAgentStepInfo] = None) -> None:
179171
input_messages = self.message_manager.get_messages()
180172
model_output = await self.get_next_action(input_messages)
181173
self.update_step_info(model_output, step_info)
182-
logger.info(f'🧠 All Memory: {step_info.memory}')
174+
logger.info(f"🧠 All Memory: {step_info.memory}")
183175
self._save_conversation(input_messages, model_output)
184176
self.message_manager._remove_last_state_message() # we dont want the whole state in the chat history
185177
self.message_manager.add_model_output(model_output)
@@ -190,7 +182,7 @@ async def step(self, step_info: Optional[CustomAgentStepInfo] = None) -> None:
190182
self._last_result = result
191183

192184
if len(result) > 0 and result[-1].is_done:
193-
logger.info(f'📄 Result: {result[-1].extracted_content}')
185+
logger.info(f"📄 Result: {result[-1].extracted_content}")
194186

195187
self.consecutive_failures = 0
196188

@@ -215,7 +207,7 @@ async def step(self, step_info: Optional[CustomAgentStepInfo] = None) -> None:
215207
async def run(self, max_steps: int = 100) -> AgentHistoryList:
216208
"""Execute the task with maximum number of steps"""
217209
try:
218-
logger.info(f'🚀 Starting task: {self.task}')
210+
logger.info(f"🚀 Starting task: {self.task}")
219211

220212
self.telemetry.capture(
221213
AgentRunTelemetryEvent(
@@ -224,13 +216,14 @@ async def run(self, max_steps: int = 100) -> AgentHistoryList:
224216
)
225217
)
226218

227-
step_info = CustomAgentStepInfo(task=self.task,
228-
add_infos=self.add_infos,
229-
step_number=1,
230-
max_steps=max_steps,
231-
memory='',
232-
task_progress=''
233-
)
219+
step_info = CustomAgentStepInfo(
220+
task=self.task,
221+
add_infos=self.add_infos,
222+
step_number=1,
223+
max_steps=max_steps,
224+
memory="",
225+
task_progress="",
226+
)
234227

235228
for step in range(max_steps):
236229
if self._too_many_failures():
@@ -240,15 +233,15 @@ async def run(self, max_steps: int = 100) -> AgentHistoryList:
240233

241234
if self.history.is_done():
242235
if (
243-
self.validate_output and step < max_steps - 1
236+
self.validate_output and step < max_steps - 1
244237
): # if last step, we dont need to validate
245238
if not await self._validate_output():
246239
continue
247240

248-
logger.info('✅ Task completed successfully')
241+
logger.info("✅ Task completed successfully")
249242
break
250243
else:
251-
logger.info('❌ Failed to complete task in maximum steps')
244+
logger.info("❌ Failed to complete task in maximum steps")
252245

253246
return self.history
254247

src/agent/custom_massage_manager.py

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@
77
from __future__ import annotations
88

99
import logging
10-
from datetime import datetime
1110
from typing import List, Optional, Type
1211

13-
from langchain_anthropic import ChatAnthropic
12+
from browser_use.agent.message_manager.service import MessageManager
13+
from browser_use.agent.message_manager.views import MessageHistory
14+
from browser_use.agent.prompts import SystemPrompt
15+
from browser_use.agent.views import ActionResult, AgentStepInfo
16+
from browser_use.browser.views import BrowserState
1417
from langchain_core.language_models import BaseChatModel
1518
from langchain_core.messages import (
16-
AIMessage,
17-
BaseMessage,
1819
HumanMessage,
1920
)
20-
from langchain_openai import ChatOpenAI
21-
22-
from browser_use.agent.message_manager.views import MessageHistory, MessageMetadata
23-
from browser_use.agent.prompts import AgentMessagePrompt, SystemPrompt
24-
from browser_use.agent.views import ActionResult, AgentOutput, AgentStepInfo
25-
from browser_use.browser.views import BrowserState
26-
from browser_use.agent.message_manager.service import MessageManager
2721

2822
from .custom_prompts import CustomAgentMessagePrompt
2923

@@ -32,31 +26,40 @@
3226

3327
class CustomMassageManager(MessageManager):
3428
def __init__(
35-
self,
36-
llm: BaseChatModel,
37-
task: str,
38-
action_descriptions: str,
39-
system_prompt_class: Type[SystemPrompt],
40-
max_input_tokens: int = 128000,
41-
estimated_tokens_per_character: int = 3,
42-
image_tokens: int = 800,
43-
include_attributes: list[str] = [],
44-
max_error_length: int = 400,
45-
max_actions_per_step: int = 10,
29+
self,
30+
llm: BaseChatModel,
31+
task: str,
32+
action_descriptions: str,
33+
system_prompt_class: Type[SystemPrompt],
34+
max_input_tokens: int = 128000,
35+
estimated_tokens_per_character: int = 3,
36+
image_tokens: int = 800,
37+
include_attributes: list[str] = [],
38+
max_error_length: int = 400,
39+
max_actions_per_step: int = 10,
4640
):
47-
super().__init__(llm, task, action_descriptions, system_prompt_class, max_input_tokens,
48-
estimated_tokens_per_character, image_tokens, include_attributes, max_error_length,
49-
max_actions_per_step)
41+
super().__init__(
42+
llm,
43+
task,
44+
action_descriptions,
45+
system_prompt_class,
46+
max_input_tokens,
47+
estimated_tokens_per_character,
48+
image_tokens,
49+
include_attributes,
50+
max_error_length,
51+
max_actions_per_step,
52+
)
5053

5154
# Move Task info to state_message
5255
self.history = MessageHistory()
5356
self._add_message_with_tokens(self.system_prompt)
5457

5558
def add_state_message(
56-
self,
57-
state: BrowserState,
58-
result: Optional[List[ActionResult]] = None,
59-
step_info: Optional[AgentStepInfo] = None,
59+
self,
60+
state: BrowserState,
61+
result: Optional[List[ActionResult]] = None,
62+
step_info: Optional[AgentStepInfo] = None,
6063
) -> None:
6164
"""Add browser state as human message"""
6265

@@ -68,7 +71,9 @@ def add_state_message(
6871
msg = HumanMessage(content=str(r.extracted_content))
6972
self._add_message_with_tokens(msg)
7073
if r.error:
71-
msg = HumanMessage(content=str(r.error)[-self.max_error_length:])
74+
msg = HumanMessage(
75+
content=str(r.error)[-self.max_error_length :]
76+
)
7277
self._add_message_with_tokens(msg)
7378
result = None # if result in history, we dont want to add it again
7479

0 commit comments

Comments
 (0)