Skip to content

Commit 72c814a

Browse files
committed
Add upload file functionality
1 parent d55b722 commit 72c814a

File tree

1 file changed

+61
-3
lines changed

1 file changed

+61
-3
lines changed

patchwork/steps/BrowserUse/BrowserUse.py

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import asyncio
2+
import logging
3+
import os
24

3-
from browser_use import Agent, Browser, BrowserConfig
5+
from browser_use import Agent, Browser, BrowserConfig, BrowserContextConfig, Controller
6+
from browser_use.agent.views import ActionResult
7+
from browser_use.browser.context import BrowserContext
48
from langchain_google_genai import ChatGoogleGenerativeAI
59
from langchain_openai import ChatOpenAI
610
from langchain_anthropic import ChatAnthropic
@@ -10,7 +14,61 @@
1014
from patchwork.steps import SimplifiedLLMOnce
1115
from patchwork.steps.BrowserUse.typed import BrowserUseInputs, BrowserUseOutputs
1216

13-
config = BrowserConfig(headless=True, disable_security=True)
17+
downloads_path = os.path.join(os.getcwd(), "downloads")
18+
logger = logging.getLogger(__name__)
19+
context_config = BrowserContextConfig(save_downloads_path=downloads_path)
20+
config = BrowserConfig(
21+
headless=True, disable_security=True, new_context_config=context_config
22+
)
23+
controller = Controller()
24+
25+
if not os.path.exists(downloads_path):
26+
os.makedirs(downloads_path)
27+
28+
29+
@controller.action(
30+
description="Upload file to interactive element with file path",
31+
)
32+
async def upload_file(index: int, path: str, browser: BrowserContext):
33+
if not os.path.exists(path):
34+
return ActionResult(error=f"File {path} does not exist")
35+
36+
dom_el = await browser.get_dom_element_by_index(index)
37+
file_upload_dom_el = dom_el.get_file_upload_element()
38+
39+
if file_upload_dom_el is None:
40+
msg = f"No file upload element found at index {index}. The element may be hidden or not an input type file"
41+
logger.info(msg)
42+
return ActionResult(error=msg)
43+
44+
file_upload_el = await browser.get_locate_element(file_upload_dom_el)
45+
46+
if file_upload_el is None:
47+
msg = f"No file upload element found at index {index}. The element may be hidden or not an input type file"
48+
logger.info(msg)
49+
return ActionResult(error=msg)
50+
51+
try:
52+
await file_upload_el.set_input_files(path)
53+
msg = f"Successfully uploaded file to index {index}"
54+
logger.info(msg)
55+
return ActionResult(extracted_content=msg, include_in_memory=True)
56+
except Exception as e:
57+
msg = f"Failed to upload file to index {index}: {str(e)}"
58+
logger.info(msg)
59+
return ActionResult(error=msg)
60+
61+
62+
@controller.action(description="Read the file content of a file given a path")
63+
async def read_file(path: str):
64+
if not os.path.exists(path):
65+
return ActionResult(error=f"File {path} does not exist")
66+
67+
with open(path, "r") as f:
68+
content = f.read()
69+
msg = f"File content: {content}"
70+
logger.info(msg)
71+
return ActionResult(extracted_content=msg, include_in_memory=True)
1472

1573

1674
class BrowserUse(Step, input_class=BrowserUseInputs, output_class=BrowserUseOutputs):
@@ -49,11 +107,11 @@ def run(self) -> dict:
49107
llm=self.llm,
50108
generate_gif=self.generate_gif,
51109
validate_output=True,
110+
controller=controller,
52111
)
53112

54113
loop = asyncio.new_event_loop()
55114
self.history = loop.run_until_complete(agent.run())
56-
57115
if "example_json" in self.inputs:
58116
return self.__format_history_as_json()
59117

0 commit comments

Comments
 (0)