huytofu92 commited on
Commit
59377f3
·
1 Parent(s): cd38811

Change to async browser

Browse files
Files changed (2) hide show
  1. browser.py +29 -12
  2. mini_agents.py +25 -10
browser.py CHANGED
@@ -1,9 +1,11 @@
1
  import subprocess
 
2
  from contextlib import contextmanager
3
  from typing import List, Optional
4
  from threading import Lock
5
  from smolagents.tools import Tool
6
  from langchain_community.tools.playwright.utils import (
 
7
  create_sync_playwright_browser
8
  )
9
  from langchain_community.agent_toolkits import PlayWrightBrowserToolkit
@@ -26,6 +28,21 @@ class BrowserManager:
26
  subprocess.run(["bash", "scripts.sh"])
27
  self.initialized = True
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  @contextmanager
30
  def get_browser_tools(self):
31
  """Get browser tools in a context that ensures proper cleanup"""
@@ -33,18 +50,16 @@ class BrowserManager:
33
  if self._browser_tools is None:
34
  with self._lock:
35
  if self._browser_tools is None:
36
- # Create only sync browser
37
- sync_browser = create_sync_playwright_browser()
 
 
 
 
 
38
 
39
- # Create toolkit with only sync browser
40
- browser_toolkit = PlayWrightBrowserToolkit.from_browser(
41
- sync_browser=sync_browser,
42
- async_browser=None
43
- )
44
- self._browser_tools = [
45
- Tool.from_langchain(tool)
46
- for tool in browser_toolkit.get_tools()
47
- ]
48
 
49
  yield self._browser_tools
50
 
@@ -59,7 +74,9 @@ class BrowserManager:
59
  for tool in self._browser_tools:
60
  if hasattr(tool, 'browser'):
61
  try:
62
- tool.browser.close()
 
 
63
  except:
64
  pass
65
  self._browser_tools = None
 
1
  import subprocess
2
+ import anyio
3
  from contextlib import contextmanager
4
  from typing import List, Optional
5
  from threading import Lock
6
  from smolagents.tools import Tool
7
  from langchain_community.tools.playwright.utils import (
8
+ create_async_playwright_browser,
9
  create_sync_playwright_browser
10
  )
11
  from langchain_community.agent_toolkits import PlayWrightBrowserToolkit
 
28
  subprocess.run(["bash", "scripts.sh"])
29
  self.initialized = True
30
 
31
+ async def _create_async_tools(self):
32
+ """Create async browser tools in the correct event loop"""
33
+ # Create browsers in the current context
34
+ async_browser = await create_async_playwright_browser()
35
+
36
+ # Create toolkit and tools
37
+ browser_toolkit = PlayWrightBrowserToolkit.from_browser(
38
+ async_browser=async_browser,
39
+ sync_browser=None # Don't use sync browser
40
+ )
41
+ return [
42
+ Tool.from_langchain(tool)
43
+ for tool in browser_toolkit.get_tools()
44
+ ]
45
+
46
  @contextmanager
47
  def get_browser_tools(self):
48
  """Get browser tools in a context that ensures proper cleanup"""
 
50
  if self._browser_tools is None:
51
  with self._lock:
52
  if self._browser_tools is None:
53
+ # Create new event loop for this thread if needed
54
+ try:
55
+ loop = anyio.get_current_loop()
56
+ except RuntimeError:
57
+ # Create new event loop in this thread
58
+ loop = anyio.new_event_loop()
59
+ anyio.set_event_loop(loop)
60
 
61
+ # Create tools in the event loop
62
+ self._browser_tools = loop.run_until_complete(self._create_async_tools())
 
 
 
 
 
 
 
63
 
64
  yield self._browser_tools
65
 
 
74
  for tool in self._browser_tools:
75
  if hasattr(tool, 'browser'):
76
  try:
77
+ # Run cleanup in event loop
78
+ loop = anyio.get_current_loop()
79
+ loop.run_until_complete(tool.browser.close())
80
  except:
81
  pass
82
  self._browser_tools = None
mini_agents.py CHANGED
@@ -9,6 +9,9 @@ from browser import browser_manager
9
  import os
10
  import logging
11
  import yaml
 
 
 
12
 
13
  logging.basicConfig(level=logging.DEBUG)
14
 
@@ -166,22 +169,34 @@ class MasterAgentWrapper:
166
  description="This agent is responsible for managing audio, vlm, arithmetic and pandas agents."
167
  )
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  def run(self, question: str) -> str:
170
  """Run the agent with thread-safe browser tools"""
171
  try:
172
  # Get browser tools in the correct context
173
  with browser_manager.get_browser_tools() as browser_tools:
174
- # Temporarily add browser tools for this run
175
- original_tools = self.master_agent.tools
176
- self.master_agent.tools = original_tools + browser_tools
177
-
178
  try:
179
- # Run the agent (using sync run since we're using sync browser)
180
- result = self.master_agent.run(question)
181
- return result
182
- finally:
183
- # Restore original tools
184
- self.master_agent.tools = original_tools
 
185
 
186
  except Exception as e:
187
  logging.error(f"Error in master agent run: {e}")
 
9
  import os
10
  import logging
11
  import yaml
12
+ import anyio
13
+ from typing import List, Optional
14
+ from smolagents.tools import Tool
15
 
16
  logging.basicConfig(level=logging.DEBUG)
17
 
 
169
  description="This agent is responsible for managing audio, vlm, arithmetic and pandas agents."
170
  )
171
 
172
+ async def _run_with_browser_tools(self, question: str, browser_tools: List[Tool]) -> str:
173
+ """Async method to run agent with browser tools"""
174
+ # Temporarily add browser tools
175
+ original_tools = self.master_agent.tools
176
+ self.master_agent.tools = original_tools + browser_tools
177
+
178
+ try:
179
+ # Run the agent using async run
180
+ result = await self.master_agent.arun(question)
181
+ return result
182
+ finally:
183
+ # Restore original tools
184
+ self.master_agent.tools = original_tools
185
+
186
  def run(self, question: str) -> str:
187
  """Run the agent with thread-safe browser tools"""
188
  try:
189
  # Get browser tools in the correct context
190
  with browser_manager.get_browser_tools() as browser_tools:
191
+ # Get or create event loop
 
 
 
192
  try:
193
+ loop = anyio.get_current_loop()
194
+ except RuntimeError:
195
+ loop = anyio.new_event_loop()
196
+ anyio.set_event_loop(loop)
197
+
198
+ # Run with browser tools in async context
199
+ return loop.run_until_complete(self._run_with_browser_tools(question, browser_tools))
200
 
201
  except Exception as e:
202
  logging.error(f"Error in master agent run: {e}")