browser-use intervention hack
frdel committed
Jan 19, 2025 at 14:43 UTC
cd82c448ae59c097aeb9aa30f6e5586923a65e63
11 files changed
+70
-5
README.md
+2
-1
@@ -4,7 +4,8 @@
4
5
# `Agent Zero`
6
7
-[](https://www.skool.com/agent-zero) [](https://discord.gg/B8KZKNsPpj) [](https://www.youtube.com/@AgentZeroFW) [](https://www.linkedin.com/in/jan-tomasek/) [](https://x.com/JanTomasekDev)
7
+[](https://github.com/sponsors/frdel) [](https://www.skool.com/agent-zero) [](https://discord.gg/B8KZKNsPpj) [](https://www.youtube.com/@AgentZeroFW) [](https://www.linkedin.com/in/jan-tomasek/) [](https://x.com/JanTomasekDev)
8
+
9
10
[Installation](./docs/installation.md) •
11
[How to update](./docs/installation.md#how-to-update-agent-zero) •
docs/res/favicon.png
Binary files /dev/null and b/docs/res/favicon.png differ
docs/res/favicon_round.png
Binary files /dev/null and b/docs/res/favicon_round.png differ
python/extensions/message_loop_prompts/.gitkeep
python/extensions/message_loop_start/.gitkeep
python/extensions/message_loop_start/_10_iteration_no.py
new
+14
@@ -0,0 +1,14 @@
1
+from python.helpers.extension import Extension
2
+from agent import Agent, LoopData
3
+
4
+DATA_NAME_ITER_NO = "iteration_no"
5
+
6
+class IterationNo(Extension):
7
+ async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
8
+ # total iteration number
9
+ no = self.agent.get_data(DATA_NAME_ITER_NO) or 0
10
+ self.agent.set_data(DATA_NAME_ITER_NO, no + 1)
11
+
12
+
13
+def get_iter_no(agent: Agent) -> int:
14
+ return agent.get_data(DATA_NAME_ITER_NO) or 0
\ No newline at end of file
python/extensions/monologue_end/.gitkeep
python/extensions/system_prompt/.gitkeep
python/tools/browser_agent.py
+38
-3
@@ -1,13 +1,14 @@
1
import asyncio
2
import json
3
import time
4
-from agent import Agent
4
+from agent import Agent, InterventionException
5
6
import models
7
from python.helpers.tool import Tool, Response
8
from python.helpers import dirty_json, files, rfc_exchange, defer, strings, persist_chat
9
from python.helpers.print_style import PrintStyle
10
from python.helpers.browser_use import browser_use
11
+from python.extensions.message_loop_start._10_iteration_no import get_iter_no
12
from pydantic import BaseModel
13
import uuid
14
@@ -24,6 +25,8 @@ class State:
25
self.task = None
26
self.use_agent = None
27
self.browser = None
28
+ self.iter_no = 0
29
+
30
31
def __del__(self):
32
self.kill_task()
@@ -42,6 +45,9 @@ class State:
45
# Await the coroutine to get the browser context
46
self.context = await self.browser.new_context()
47
48
+ # override async methods to create hooks
49
+ self.override_hooks()
50
+
51
# Add init script to the context - this will be applied to all new pages
52
await self.context._initialize_session()
53
pw_context = self.context.session.context # type: ignore
@@ -68,6 +74,7 @@ class State:
74
self.context = None
75
self.use_agent = None
76
self.browser = None
77
+ self.iter_no = 0
78
79
async def _run_task(self, task: str):
80
@@ -117,9 +124,34 @@ class State:
124
system_prompt_class=CustomSystemPrompt,
125
controller=controller,
126
)
127
+
128
+ self.iter_no = get_iter_no(self.agent)
129
+
130
+ # orig_err_hnd = self.use_agent._handle_step_error
131
+ # def new_err_hnd(*args, **kwargs):
132
+ # if isinstance(args[0], InterventionException):
133
+ # raise args[0]
134
+ # return orig_err_hnd(*args, **kwargs)
135
+ # self.use_agent._handle_step_error = new_err_hnd
136
+
137
result = await self.use_agent.run()
138
return result
139
140
+ def override_hooks(self):
141
+ # override async function to create a hook
142
+ def override_hook(func):
143
+ async def wrapper(*args, **kwargs):
144
+ await self.agent.wait_if_paused()
145
+ if self.iter_no != get_iter_no(self.agent):
146
+ raise InterventionException("Task cancelled")
147
+ return await func(*args, **kwargs)
148
+ return wrapper
149
+
150
+ if self.context:
151
+ self.context.get_state = override_hook(self.context.get_state)
152
+ self.context.get_session = override_hook(self.context.get_session)
153
+ self.context.remove_highlights = override_hook(self.context.remove_highlights)
154
+
155
async def get_page(self):
156
if self.use_agent:
157
return await self.use_agent.browser_context.get_current_page()
@@ -150,8 +182,11 @@ class BrowserAgent(Tool):
182
# collect result
183
result = await task.result()
184
answer = result.final_result()
153
- answer_data = dirty_json.DirtyJson.parse_string(answer)
154
- answer_text = strings.dict_to_text(answer_data) # type: ignore
185
+ try:
186
+ answer_data = dirty_json.DirtyJson.parse_string(answer)
187
+ answer_text = strings.dict_to_text(answer_data) # type: ignore
188
+ except Exception as e:
189
+ answer_text = answer
190
self.log.update(answer=answer_text)
191
return Response(message=answer, break_loop=False)
192
webui/index.html
+1
-1
@@ -457,7 +457,7 @@
457
<div :class="{'field': true, 'field-full': field.type === 'textarea'}">
458
<div class="field-label">
459
<div class="field-title" x-text="field.title"></div>
460
- <div class="field-description" x-html="field.description"></div>
460
+ <div class="field-description" x-html="field.description || ''"></div>
461
</div>
462
463
<div class="field-control">
webui/public/favicon_round.svg
new
+15
@@ -0,0 +1,15 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+<svg width="100%" height="100%" viewBox="0 0 960 960" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <g transform="matrix(1.07993,0,0,1.07993,-76.6057,-32.2424)">
5
+ <circle cx="515.545" cy="474.371" r="442.821" style="fill:rgb(1,4,26);"/>
6
+ </g>
7
+ <g transform="matrix(1,0,0,1,0,-61.814)">
8
+ <g transform="matrix(1.03321,0,0,1.03321,-15.9385,-15.938)">
9
+ <path d="M717.77,788.27C638.99,652.89 559.87,516.92 479.15,378.22C399.29,516.59 320.58,652.95 241.99,789.12L120,789.12C239.91,581.87 479.49,170.89 479.49,170.89C479.49,170.89 720.12,580.92 840,788.27L717.77,788.27Z" style="fill:white;fill-rule:nonzero;"/>
10
+ </g>
11
+ <g transform="matrix(1.03321,0,0,1.03321,-15.9385,-15.938)">
12
+ <path d="M633.08,788.85L323.54,788.85C344.15,753.01 364.09,718.33 383.88,683.93L574.1,683.93C593.38,718.23 612.57,752.36 633.08,788.85Z" style="fill:white;fill-rule:nonzero;"/>
13
+ </g>
14
+ </g>
15
+</svg>