frdel commited on
Commit
0d362e5
·
1 Parent(s): dcd3ab7

browser-use intervention hack

Browse files
README.md CHANGED
@@ -4,7 +4,8 @@
4
 
5
  # `Agent Zero`
6
 
7
- [![Join our Skool Community](https://img.shields.io/badge/Skool-Join%20our%20Community-4A90E2?style=for-the-badge&logo=skool&logoColor=white)](https://www.skool.com/agent-zero) [![Join our Discord](https://img.shields.io/badge/Discord-Join%20our%20server-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/B8KZKNsPpj) [![Subscribe on YouTube](https://img.shields.io/badge/YouTube-Subscribe-red?style=for-the-badge&logo=youtube&logoColor=white)](https://www.youtube.com/@AgentZeroFW) [![Connect on LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-blue?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/jan-tomasek/) [![Follow on X.com](https://img.shields.io/badge/X.com-Follow-1DA1F2?style=for-the-badge&logo=x&logoColor=white)](https://x.com/JanTomasekDev)
 
8
 
9
  [Installation](./docs/installation.md) •
10
  [How to update](./docs/installation.md#how-to-update-agent-zero) •
 
4
 
5
  # `Agent Zero`
6
 
7
+ [![Thanks to Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-Thanks%20to%20Sponsors-FF69B4?style=for-the-badge&logo=githubsponsors&logoColor=white)](https://github.com/sponsors/frdel) [![Join our Skool Community](https://img.shields.io/badge/Skool-Join%20our%20Community-4A90E2?style=for-the-badge&logo=skool&logoColor=white)](https://www.skool.com/agent-zero) [![Join our Discord](https://img.shields.io/badge/Discord-Join%20our%20server-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/B8KZKNsPpj) [![Subscribe on YouTube](https://img.shields.io/badge/YouTube-Subscribe-red?style=for-the-badge&logo=youtube&logoColor=white)](https://www.youtube.com/@AgentZeroFW) [![Connect on LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-blue?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/jan-tomasek/) [![Follow on X.com](https://img.shields.io/badge/X.com-Follow-1DA1F2?style=for-the-badge&logo=x&logoColor=white)](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 ADDED

Git LFS Details

  • SHA256: 620fffd3a077aa44a8d9b0124fbab19574a8c8c7c7c988e0d423ef6ac96be7f5
  • Pointer size: 130 Bytes
  • Size of remote file: 39.6 kB
docs/res/favicon_round.png ADDED

Git LFS Details

  • SHA256: 2f04689d468fac65bc553686d553a338f5bb377653c0873aee55a87c6738b65a
  • Pointer size: 130 Bytes
  • Size of remote file: 51.9 kB
python/extensions/message_loop_prompts/.gitkeep ADDED
File without changes
python/extensions/message_loop_start/.gitkeep ADDED
File without changes
python/extensions/message_loop_start/_10_iteration_no.py ADDED
@@ -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
python/extensions/monologue_end/.gitkeep ADDED
File without changes
python/extensions/system_prompt/.gitkeep ADDED
File without changes
python/tools/browser_agent.py CHANGED
@@ -1,13 +1,14 @@
1
  import asyncio
2
  import json
3
  import time
4
- from agent import Agent
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 pydantic import BaseModel
12
  import uuid
13
 
@@ -24,6 +25,8 @@ class State:
24
  self.task = None
25
  self.use_agent = None
26
  self.browser = None
 
 
27
 
28
  def __del__(self):
29
  self.kill_task()
@@ -42,6 +45,9 @@ class State:
42
  # Await the coroutine to get the browser context
43
  self.context = await self.browser.new_context()
44
 
 
 
 
45
  # Add init script to the context - this will be applied to all new pages
46
  await self.context._initialize_session()
47
  pw_context = self.context.session.context # type: ignore
@@ -68,6 +74,7 @@ class State:
68
  self.context = None
69
  self.use_agent = None
70
  self.browser = None
 
71
 
72
  async def _run_task(self, task: str):
73
 
@@ -117,9 +124,34 @@ class State:
117
  system_prompt_class=CustomSystemPrompt,
118
  controller=controller,
119
  )
 
 
 
 
 
 
 
 
 
 
120
  result = await self.use_agent.run()
121
  return result
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  async def get_page(self):
124
  if self.use_agent:
125
  return await self.use_agent.browser_context.get_current_page()
@@ -150,8 +182,11 @@ class BrowserAgent(Tool):
150
  # collect result
151
  result = await task.result()
152
  answer = result.final_result()
153
- answer_data = dirty_json.DirtyJson.parse_string(answer)
154
- answer_text = strings.dict_to_text(answer_data) # type: ignore
 
 
 
155
  self.log.update(answer=answer_text)
156
  return Response(message=answer, break_loop=False)
157
 
 
1
  import asyncio
2
  import json
3
  import time
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
 
 
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()
 
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
 
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
 
 
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()
 
182
  # collect result
183
  result = await task.result()
184
  answer = result.final_result()
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 CHANGED
@@ -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>
461
  </div>
462
 
463
  <div class="field-control">
 
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>
461
  </div>
462
 
463
  <div class="field-control">
webui/public/favicon_round.svg ADDED