varun324242 commited on
Commit
06ba83e
·
verified ·
1 Parent(s): 75d0729

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .env +11 -0
  2. .github/workflows/update_space.yml +28 -0
  3. .gradio/certificate.pem +31 -0
  4. BrowsingAgent/BrowsingAgent.py +166 -0
  5. BrowsingAgent/__init__.py +1 -0
  6. BrowsingAgent/__pycache__/BrowsingAgent.cpython-312.pyc +0 -0
  7. BrowsingAgent/__pycache__/__init__.cpython-312.pyc +0 -0
  8. BrowsingAgent/instructions.md +21 -0
  9. BrowsingAgent/requirements.txt +3 -0
  10. BrowsingAgent/tools/ClickElement.py +59 -0
  11. BrowsingAgent/tools/ExportFile.py +45 -0
  12. BrowsingAgent/tools/GoBack.py +22 -0
  13. BrowsingAgent/tools/ReadURL.py +44 -0
  14. BrowsingAgent/tools/Scroll.py +53 -0
  15. BrowsingAgent/tools/SelectDropdown.py +58 -0
  16. BrowsingAgent/tools/SendKeys.py +73 -0
  17. BrowsingAgent/tools/SolveCaptcha.py +238 -0
  18. BrowsingAgent/tools/WebPageSummarizer.py +39 -0
  19. BrowsingAgent/tools/__init__.py +9 -0
  20. BrowsingAgent/tools/__pycache__/ClickElement.cpython-312.pyc +0 -0
  21. BrowsingAgent/tools/__pycache__/ExportFile.cpython-312.pyc +0 -0
  22. BrowsingAgent/tools/__pycache__/GoBack.cpython-312.pyc +0 -0
  23. BrowsingAgent/tools/__pycache__/ReadURL.cpython-312.pyc +0 -0
  24. BrowsingAgent/tools/__pycache__/Scroll.cpython-312.pyc +0 -0
  25. BrowsingAgent/tools/__pycache__/SelectDropdown.cpython-312.pyc +0 -0
  26. BrowsingAgent/tools/__pycache__/SendKeys.cpython-312.pyc +0 -0
  27. BrowsingAgent/tools/__pycache__/SolveCaptcha.cpython-312.pyc +0 -0
  28. BrowsingAgent/tools/__pycache__/WebPageSummarizer.cpython-312.pyc +0 -0
  29. BrowsingAgent/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  30. BrowsingAgent/tools/util/__init__.py +3 -0
  31. BrowsingAgent/tools/util/__pycache__/__init__.cpython-312.pyc +0 -0
  32. BrowsingAgent/tools/util/__pycache__/get_b64_screenshot.cpython-312.pyc +0 -0
  33. BrowsingAgent/tools/util/__pycache__/highlights.cpython-312.pyc +0 -0
  34. BrowsingAgent/tools/util/__pycache__/selenium.cpython-312.pyc +0 -0
  35. BrowsingAgent/tools/util/get_b64_screenshot.py +8 -0
  36. BrowsingAgent/tools/util/highlights.py +139 -0
  37. BrowsingAgent/tools/util/selenium.py +154 -0
  38. CompetitorTrackingAgent/CompetitorTrackingAgent.py +19 -0
  39. CompetitorTrackingAgent/__init__.py +1 -0
  40. CompetitorTrackingAgent/__pycache__/CompetitorTrackingAgent.cpython-312.pyc +0 -0
  41. CompetitorTrackingAgent/__pycache__/__init__.cpython-312.pyc +0 -0
  42. CompetitorTrackingAgent/instructions.md +11 -0
  43. CompetitorTrackingAgent/tools/WebScrapingTool.py +59 -0
  44. CompetitorTrackingAgent/tools/__pycache__/WebScrapingTool.cpython-312.pyc +0 -0
  45. DataAnalystAgent/DataAnalystAgent.py +19 -0
  46. DataAnalystAgent/__init__.py +1 -0
  47. DataAnalystAgent/__pycache__/DataAnalystAgent.cpython-312.pyc +0 -0
  48. DataAnalystAgent/__pycache__/__init__.cpython-312.pyc +0 -0
  49. DataAnalystAgent/instructions.md +11 -0
  50. DataAnalystAgent/tools/DataAnalysisTool.py +89 -0
.env ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ OPENAI_API_KEY=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
2
+ OPENAI_MODEL=gpt-4-1106-preview
3
+ OPENAI_ORGANIZATION=your_openai_org_id_here
4
+ GROQ_API_KEY=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
5
+ DEEPGRAM_API_KEY=your_deepgram_api_key_here
6
+ GROQ_API_KEY=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
7
+ MAX_TOKENS=4000
8
+ TEMPERATURE=0.3
9
+
10
+ PORT=5002
11
+ HOST=0.0.0.0
.github/workflows/update_space.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Run Python script
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - y
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v2
18
+ with:
19
+ python-version: '3.9'
20
+
21
+ - name: Install Gradio
22
+ run: python -m pip install gradio
23
+
24
+ - name: Log in to Hugging Face
25
+ run: python -c 'import huggingface_hub; huggingface_hub.login(token="${{ secrets.hf_token }}")'
26
+
27
+ - name: Deploy to Spaces
28
+ run: gradio deploy
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
3
+ TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
4
+ cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
5
+ WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
6
+ ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
7
+ MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
8
+ h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
9
+ 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
10
+ A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
11
+ T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
12
+ B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
13
+ B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
14
+ KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
15
+ OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
16
+ jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
17
+ qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
18
+ rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
19
+ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
20
+ hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
21
+ ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
22
+ 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
23
+ NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
24
+ ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
25
+ TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
26
+ jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
27
+ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
28
+ 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
29
+ mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
30
+ emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
31
+ -----END CERTIFICATE-----
BrowsingAgent/BrowsingAgent.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import re
3
+
4
+ from agency_swarm.agents import Agent
5
+ from agency_swarm.tools.oai import FileSearch
6
+ from typing_extensions import override
7
+ import base64
8
+
9
+
10
+ class BrowsingAgent(Agent):
11
+ SCREENSHOT_FILE_NAME = "screenshot.jpg"
12
+
13
+ def __init__(self, selenium_config=None, **kwargs):
14
+ from .tools.util.selenium import set_selenium_config
15
+ super().__init__(
16
+ name="BrowsingAgent",
17
+ description="This agent is designed to navigate and search web effectively.",
18
+ instructions="./instructions.md",
19
+ files_folder="./files",
20
+ schemas_folder="./schemas",
21
+ tools=[],
22
+ tools_folder="./tools",
23
+ temperature=0,
24
+ max_prompt_tokens=16000,
25
+ model="gpt-4o",
26
+ validation_attempts=25,
27
+ **kwargs
28
+ )
29
+ if selenium_config is not None:
30
+ set_selenium_config(selenium_config)
31
+
32
+ self.prev_message = ""
33
+
34
+ @override
35
+ def response_validator(self, message):
36
+ from .tools.util.selenium import get_web_driver, set_web_driver
37
+ from .tools.util import highlight_elements_with_labels, remove_highlight_and_labels
38
+ from selenium.webdriver.common.by import By
39
+ from selenium.webdriver.support.select import Select
40
+
41
+ # Filter out everything in square brackets
42
+ filtered_message = re.sub(r'\[.*?\]', '', message).strip()
43
+
44
+ if filtered_message and self.prev_message == filtered_message:
45
+ raise ValueError("Do not repeat yourself. If you are stuck, try a different approach or search in google for the page you are looking for directly.")
46
+
47
+ self.prev_message = filtered_message
48
+
49
+ if "[send screenshot]" in message.lower():
50
+ wd = get_web_driver()
51
+ remove_highlight_and_labels(wd)
52
+ self.take_screenshot()
53
+ response_text = "Here is the screenshot of the current web page:"
54
+
55
+ elif '[highlight clickable elements]' in message.lower():
56
+ wd = get_web_driver()
57
+ highlight_elements_with_labels(wd, 'a, button, div[onclick], div[role="button"], div[tabindex], '
58
+ 'span[onclick], span[role="button"], span[tabindex]')
59
+ self._shared_state.set("elements_highlighted", 'a, button, div[onclick], div[role="button"], div[tabindex], '
60
+ 'span[onclick], span[role="button"], span[tabindex]')
61
+
62
+ self.take_screenshot()
63
+
64
+ all_elements = wd.find_elements(By.CSS_SELECTOR, '.highlighted-element')
65
+
66
+ all_element_texts = [element.text for element in all_elements]
67
+
68
+ element_texts_json = {}
69
+ for i, element_text in enumerate(all_element_texts):
70
+ element_texts_json[str(i + 1)] = self.remove_unicode(element_text)
71
+
72
+ element_texts_json = {k: v for k, v in element_texts_json.items() if v}
73
+
74
+ element_texts_formatted = ", ".join([f"{k}: {v}" for k, v in element_texts_json.items()])
75
+
76
+ response_text = ("Here is the screenshot of the current web page with highlighted clickable elements. \n\n"
77
+ "Texts of the elements are: " + element_texts_formatted + ".\n\n"
78
+ "Elements without text are not shown, but are available on screenshot. \n"
79
+ "Please make sure to analyze the screenshot to find the clickable element you need to click on.")
80
+
81
+ elif '[highlight text fields]' in message.lower():
82
+ wd = get_web_driver()
83
+ highlight_elements_with_labels(wd, 'input, textarea')
84
+ self._shared_state.set("elements_highlighted", "input, textarea")
85
+
86
+ self.take_screenshot()
87
+
88
+ all_elements = wd.find_elements(By.CSS_SELECTOR, '.highlighted-element')
89
+
90
+ all_element_texts = [element.text for element in all_elements]
91
+
92
+ element_texts_json = {}
93
+ for i, element_text in enumerate(all_element_texts):
94
+ element_texts_json[str(i + 1)] = self.remove_unicode(element_text)
95
+
96
+ element_texts_formatted = ", ".join([f"{k}: {v}" for k, v in element_texts_json.items()])
97
+
98
+ response_text = ("Here is the screenshot of the current web page with highlighted text fields: \n"
99
+ "Texts of the elements are: " + element_texts_formatted + ".\n"
100
+ "Please make sure to analyze the screenshot to find the text field you need to fill.")
101
+
102
+ elif '[highlight dropdowns]' in message.lower():
103
+ wd = get_web_driver()
104
+ highlight_elements_with_labels(wd, 'select')
105
+ self._shared_state.set("elements_highlighted", "select")
106
+
107
+ self.take_screenshot()
108
+
109
+ all_elements = wd.find_elements(By.CSS_SELECTOR, '.highlighted-element')
110
+
111
+ all_selector_values = {}
112
+
113
+ i = 0
114
+ for element in all_elements:
115
+ select = Select(element)
116
+ options = select.options
117
+ selector_values = {}
118
+ for j, option in enumerate(options):
119
+ selector_values[str(j)] = option.text
120
+ if j > 10:
121
+ break
122
+ all_selector_values[str(i + 1)] = selector_values
123
+
124
+ all_selector_values = {k: v for k, v in all_selector_values.items() if v}
125
+ all_selector_values_formatted = ", ".join([f"{k}: {v}" for k, v in all_selector_values.items()])
126
+
127
+ response_text = ("Here is the screenshot with highlighted dropdowns. \n"
128
+ "Selector values are: " + all_selector_values_formatted + ".\n"
129
+ "Please make sure to analyze the screenshot to find the dropdown you need to select.")
130
+
131
+ else:
132
+ return message
133
+
134
+ set_web_driver(wd)
135
+ content = self.create_response_content(response_text)
136
+ raise ValueError(content)
137
+
138
+ def take_screenshot(self):
139
+ from .tools.util.selenium import get_web_driver
140
+ from .tools.util import get_b64_screenshot
141
+ wd = get_web_driver()
142
+ screenshot = get_b64_screenshot(wd)
143
+ screenshot_data = base64.b64decode(screenshot)
144
+ with open(self.SCREENSHOT_FILE_NAME, "wb") as screenshot_file:
145
+ screenshot_file.write(screenshot_data)
146
+
147
+ def create_response_content(self, response_text):
148
+ with open(self.SCREENSHOT_FILE_NAME, "rb") as file:
149
+ file_id = self.client.files.create(
150
+ file=file,
151
+ purpose="vision",
152
+ ).id
153
+
154
+ content = [
155
+ {"type": "text", "text": response_text},
156
+ {
157
+ "type": "image_file",
158
+ "image_file": {"file_id": file_id}
159
+ }
160
+ ]
161
+ return content
162
+
163
+ # Function to check for Unicode escape sequences
164
+ def remove_unicode(self, data):
165
+ return re.sub(r'[^\x00-\x7F]+', '', data)
166
+
BrowsingAgent/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .BrowsingAgent import BrowsingAgent
BrowsingAgent/__pycache__/BrowsingAgent.cpython-312.pyc ADDED
Binary file (8.19 kB). View file
 
BrowsingAgent/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (207 Bytes). View file
 
BrowsingAgent/instructions.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Browsing Agent Instructions
2
+
3
+ As an advanced browsing agent, you are equipped with specialized tools to navigate and search the web effectively. Your primary objective is to fulfill the user's requests by efficiently utilizing these tools.
4
+
5
+ ### Primary Instructions:
6
+
7
+ 1. **Avoid Guessing URLs**: Never attempt to guess the direct URL. Always perform a Google search if applicable, or return to your previous search results.
8
+ 2. **Navigating to New Pages**: Always use the `ClickElement` tool to open links when navigating to a new web page from the current source. Do not guess the direct URL.
9
+ 3. **Single Page Interaction**: You can only open and interact with one web page at a time. The previous web page will be closed when you open a new one. To navigate back, use the `GoBack` tool.
10
+ 4. **Requesting Screenshots**: Before using tools that interact with the web page, ask the user to send you the appropriate screenshot using one of the commands below.
11
+
12
+ ### Commands to Request Screenshots:
13
+
14
+ - **'[send screenshot]'**: Sends the current browsing window as an image. Use this command if the user asks what is on the page.
15
+ - **'[highlight clickable elements]'**: Highlights all clickable elements on the current web page. This must be done before using the `ClickElement` tool.
16
+ - **'[highlight text fields]'**: Highlights all text fields on the current web page. This must be done before using the `SendKeys` tool.
17
+ - **'[highlight dropdowns]'**: Highlights all dropdowns on the current web page. This must be done before using the `SelectDropdown` tool.
18
+
19
+ ### Important Reminders:
20
+
21
+ - Only open and interact with one web page at a time. Do not attempt to read or click on multiple links simultaneously. Complete your interactions with the current web page before proceeding to a different source.
BrowsingAgent/requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ selenium
2
+ webdriver-manager
3
+ selenium_stealth
BrowsingAgent/tools/ClickElement.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+
3
+ from pydantic import Field
4
+ from selenium.webdriver.common.by import By
5
+
6
+ from agency_swarm.tools import BaseTool
7
+ from .util import get_web_driver, set_web_driver
8
+ from .util.highlights import remove_highlight_and_labels
9
+
10
+
11
+ class ClickElement(BaseTool):
12
+ """
13
+ This tool clicks on an element on the current web page based on its number.
14
+
15
+ Before using this tool make sure to highlight clickable elements on the page by outputting '[highlight clickable elements]' message.
16
+ """
17
+ element_number: int = Field(
18
+ ...,
19
+ description="The number of the element to click on. The element numbers are displayed on the page after highlighting elements.",
20
+ )
21
+
22
+ def run(self):
23
+ wd = get_web_driver()
24
+
25
+ if 'button' not in self._shared_state.get("elements_highlighted", ""):
26
+ raise ValueError("Please highlight clickable elements on the page first by outputting '[highlight clickable elements]' message. You must output just the message without calling the tool first, so the user can respond with the screenshot.")
27
+
28
+ all_elements = wd.find_elements(By.CSS_SELECTOR, '.highlighted-element')
29
+
30
+ # iterate through all elements with a number in the text
31
+ try:
32
+ element_text = all_elements[self.element_number - 1].text
33
+ element_text = element_text.strip() if element_text else ""
34
+ # Subtract 1 because sequence numbers start at 1, but list indices start at 0
35
+ try:
36
+ all_elements[self.element_number - 1].click()
37
+ except Exception as e:
38
+ if "element click intercepted" in str(e).lower():
39
+ wd.execute_script("arguments[0].click();", all_elements[self.element_number - 1])
40
+ else:
41
+ raise e
42
+
43
+ time.sleep(3)
44
+
45
+ result = f"Clicked on element {self.element_number}. Text on clicked element: '{element_text}'. Current URL is {wd.current_url} To further analyze the page, output '[send screenshot]' command."
46
+ except IndexError:
47
+ result = "Element number is invalid. Please try again with a valid element number."
48
+ except Exception as e:
49
+ result = str(e)
50
+
51
+ wd = remove_highlight_and_labels(wd)
52
+
53
+ wd.execute_script("document.body.style.zoom='1.5'")
54
+
55
+ set_web_driver(wd)
56
+
57
+ self._shared_state.set("elements_highlighted", "")
58
+
59
+ return result
BrowsingAgent/tools/ExportFile.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import os
3
+
4
+ from agency_swarm.tools import BaseTool
5
+ from .util import get_web_driver
6
+
7
+
8
+ class ExportFile(BaseTool):
9
+ """This tool converts the current full web page into a file and returns its file_id. You can then send this file id back to the user for further processing."""
10
+
11
+ def run(self):
12
+ wd = get_web_driver()
13
+ from agency_swarm import get_openai_client
14
+ client = get_openai_client()
15
+
16
+ # Define the parameters for the PDF
17
+ params = {
18
+ 'landscape': False,
19
+ 'displayHeaderFooter': False,
20
+ 'printBackground': True,
21
+ 'preferCSSPageSize': True,
22
+ }
23
+
24
+ # Execute the command to print to PDF
25
+ result = wd.execute_cdp_cmd('Page.printToPDF', params)
26
+ pdf = result['data']
27
+
28
+ pdf_bytes = base64.b64decode(pdf)
29
+
30
+ # Save the PDF to a file
31
+ with open("exported_file.pdf", "wb") as f:
32
+ f.write(pdf_bytes)
33
+
34
+ file_id = client.files.create(file=open("exported_file.pdf", "rb"), purpose="assistants",).id
35
+
36
+ self._shared_state.set("file_id", file_id)
37
+
38
+ return "Success. File exported with id: `" + file_id + "` You can now send this file id back to the user."
39
+
40
+
41
+ if __name__ == "__main__":
42
+ wd = get_web_driver()
43
+ wd.get("https://www.google.com")
44
+ tool = ExportFile()
45
+ tool.run()
BrowsingAgent/tools/GoBack.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+
3
+ from agency_swarm.tools import BaseTool
4
+
5
+ from .util.selenium import get_web_driver, set_web_driver
6
+
7
+
8
+ class GoBack(BaseTool):
9
+ """W
10
+ This tool allows you to go back 1 page in the browser history. Use it in case of a mistake or if a page shows you unexpected content.
11
+ """
12
+
13
+ def run(self):
14
+ wd = get_web_driver()
15
+
16
+ wd.back()
17
+
18
+ time.sleep(3)
19
+
20
+ set_web_driver(wd)
21
+
22
+ return "Success. Went back 1 page. Current URL is: " + wd.current_url
BrowsingAgent/tools/ReadURL.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+
3
+ from pydantic import Field
4
+
5
+ from agency_swarm.tools import BaseTool
6
+ from .util.selenium import get_web_driver, set_web_driver
7
+
8
+
9
+ class ReadURL(BaseTool):
10
+ """
11
+ This tool reads a single URL and opens it in your current browser window. For each new source, either navigate directly to a URL that you believe contains the answer to the user's question or perform a Google search (e.g., 'https://google.com/search?q=search') if necessary.
12
+
13
+ If you are unsure of the direct URL, do not guess. Instead, use the ClickElement tool to click on links that might contain the desired information on the current web page.
14
+
15
+ Note: This tool only supports opening one URL at a time. The previous URL will be closed when you open a new one.
16
+ """
17
+ chain_of_thought: str = Field(
18
+ ..., description="Think step-by-step about where you need to navigate next to find the necessary information.",
19
+ exclude=True
20
+ )
21
+ url: str = Field(
22
+ ..., description="URL of the webpage.", examples=["https://google.com/search?q=search"]
23
+ )
24
+
25
+ class ToolConfig:
26
+ one_call_at_a_time: bool = True
27
+
28
+ def run(self):
29
+ wd = get_web_driver()
30
+
31
+ wd.get(self.url)
32
+
33
+ time.sleep(2)
34
+
35
+ set_web_driver(wd)
36
+
37
+ self._shared_state.set("elements_highlighted", "")
38
+
39
+ return "Current URL is: " + wd.current_url + "\n" + "Please output '[send screenshot]' next to analyze the current web page or '[highlight clickable elements]' for further navigation."
40
+
41
+
42
+ if __name__ == "__main__":
43
+ tool = ReadURL(url="https://google.com")
44
+ print(tool.run())
BrowsingAgent/tools/Scroll.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Literal
2
+
3
+ from pydantic import Field
4
+
5
+ from agency_swarm.tools import BaseTool
6
+ from .util.selenium import get_web_driver, set_web_driver
7
+
8
+
9
+ class Scroll(BaseTool):
10
+ """
11
+ This tool allows you to scroll the current web page up or down by 1 screen height.
12
+ """
13
+ direction: Literal["up", "down"] = Field(
14
+ ..., description="Direction to scroll."
15
+ )
16
+
17
+ def run(self):
18
+ wd = get_web_driver()
19
+
20
+ height = wd.get_window_size()['height']
21
+
22
+ # Get the zoom level
23
+ zoom_level = wd.execute_script("return document.body.style.zoom || '1';")
24
+ zoom_level = float(zoom_level.strip('%')) / 100 if '%' in zoom_level else float(zoom_level)
25
+
26
+ # Adjust height by zoom level
27
+ adjusted_height = height / zoom_level
28
+
29
+ current_scroll_position = wd.execute_script("return window.pageYOffset;")
30
+ total_scroll_height = wd.execute_script("return document.body.scrollHeight;")
31
+
32
+ result = ""
33
+
34
+ if self.direction == "up":
35
+ if current_scroll_position == 0:
36
+ # Reached the top of the page
37
+ result = "Reached the top of the page. Cannot scroll up any further.\n"
38
+ else:
39
+ wd.execute_script(f"window.scrollBy(0, -{adjusted_height});")
40
+ result = "Scrolled up by 1 screen height. Make sure to output '[send screenshot]' command to analyze the page after scrolling."
41
+
42
+ elif self.direction == "down":
43
+ if current_scroll_position + adjusted_height >= total_scroll_height:
44
+ # Reached the bottom of the page
45
+ result = "Reached the bottom of the page. Cannot scroll down any further.\n"
46
+ else:
47
+ wd.execute_script(f"window.scrollBy(0, {adjusted_height});")
48
+ result = "Scrolled down by 1 screen height. Make sure to output '[send screenshot]' command to analyze the page after scrolling."
49
+
50
+ set_web_driver(wd)
51
+
52
+ return result
53
+
BrowsingAgent/tools/SelectDropdown.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict
2
+ from pydantic import Field, model_validator
3
+ from selenium.webdriver.common.by import By
4
+ from selenium.webdriver.support.select import Select
5
+
6
+ from agency_swarm.tools import BaseTool
7
+ from .util import get_web_driver, set_web_driver
8
+ from .util.highlights import remove_highlight_and_labels
9
+
10
+
11
+ class SelectDropdown(BaseTool):
12
+ """
13
+ This tool selects an option in a dropdown on the current web page based on the description of that element and which option to select.
14
+
15
+ Before using this tool make sure to highlight dropdown elements on the page by outputting '[highlight dropdowns]' message.
16
+ """
17
+
18
+ key_value_pairs: Dict[str, str] = Field(...,
19
+ description="A dictionary where the key is the sequence number of the dropdown element and the value is the index of the option to select.",
20
+ examples=[{"1": 0, "2": 1}, {"3": 2}]
21
+ )
22
+
23
+ @model_validator(mode='before')
24
+ @classmethod
25
+ def check_key_value_pairs(cls, data):
26
+ if not data.get('key_value_pairs'):
27
+ raise ValueError(
28
+ "key_value_pairs is required. Example format: "
29
+ "key_value_pairs={'1': 0, '2': 1}"
30
+ )
31
+ return data
32
+
33
+ def run(self):
34
+ wd = get_web_driver()
35
+
36
+ if 'select' not in self._shared_state.get("elements_highlighted", ""):
37
+ raise ValueError("Please highlight dropdown elements on the page first by outputting '[highlight dropdowns]' message. You must output just the message without calling the tool first, so the user can respond with the screenshot.")
38
+
39
+ all_elements = wd.find_elements(By.CSS_SELECTOR, '.highlighted-element')
40
+
41
+ try:
42
+ for key, value in self.key_value_pairs.items():
43
+ key = int(key)
44
+ element = all_elements[key - 1]
45
+
46
+ select = Select(element)
47
+
48
+ # Select the first option (index 0)
49
+ select.select_by_index(int(value))
50
+ result = f"Success. Option is selected in the dropdown. To further analyze the page, output '[send screenshot]' command."
51
+ except Exception as e:
52
+ result = str(e)
53
+
54
+ remove_highlight_and_labels(wd)
55
+
56
+ set_web_driver(wd)
57
+
58
+ return result
BrowsingAgent/tools/SendKeys.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from typing import Dict
3
+
4
+ from pydantic import Field
5
+ from selenium.webdriver import Keys
6
+ from selenium.webdriver.common.by import By
7
+
8
+ from agency_swarm.tools import BaseTool
9
+ from .util import get_web_driver, set_web_driver
10
+ from .util.highlights import remove_highlight_and_labels
11
+
12
+
13
+ from pydantic import model_validator
14
+
15
+ class SendKeys(BaseTool):
16
+ """
17
+ This tool sends keys into input fields on the current webpage based on the description of that element and what needs to be typed. It then clicks "Enter" on the last element to submit the form. You do not need to tell it to press "Enter"; it will do that automatically.
18
+
19
+ Before using this tool make sure to highlight the input elements on the page by outputting '[highlight text fields]' message.
20
+ """
21
+ elements_and_texts: Dict[int, str] = Field(...,
22
+ description="A dictionary where the key is the element number and the value is the text to be typed.",
23
+ examples=[
24
+ {52: "johndoe@gmail.com", 53: "password123"},
25
+ {3: "John Doe", 4: "123 Main St"},
26
+ ]
27
+ )
28
+
29
+ @model_validator(mode='before')
30
+ @classmethod
31
+ def check_elements_and_texts(cls, data):
32
+ if not data.get('elements_and_texts'):
33
+ raise ValueError(
34
+ "elements_and_texts is required. Example format: "
35
+ "elements_and_texts={1: 'John Doe', 2: '123 Main St'}"
36
+ )
37
+ return data
38
+
39
+ def run(self):
40
+ wd = get_web_driver()
41
+ if 'input' not in self._shared_state.get("elements_highlighted", ""):
42
+ raise ValueError("Please highlight input elements on the page first by outputting '[highlight text fields]' message. You must output just the message without calling the tool first, so the user can respond with the screenshot.")
43
+
44
+ all_elements = wd.find_elements(By.CSS_SELECTOR, '.highlighted-element')
45
+
46
+ i = 0
47
+ try:
48
+ for key, value in self.elements_and_texts.items():
49
+ key = int(key)
50
+ element = all_elements[key - 1]
51
+
52
+ try:
53
+ element.click()
54
+ element.send_keys(Keys.CONTROL + "a") # Select all text in input
55
+ element.send_keys(Keys.DELETE)
56
+ element.clear()
57
+ except Exception as e:
58
+ pass
59
+ element.send_keys(value)
60
+ # send enter key to the last element
61
+ if i == len(self.elements_and_texts) - 1:
62
+ element.send_keys(Keys.RETURN)
63
+ time.sleep(3)
64
+ i += 1
65
+ result = f"Sent input to element and pressed Enter. Current URL is {wd.current_url} To further analyze the page, output '[send screenshot]' command."
66
+ except Exception as e:
67
+ result = str(e)
68
+
69
+ remove_highlight_and_labels(wd)
70
+
71
+ set_web_driver(wd)
72
+
73
+ return result
BrowsingAgent/tools/SolveCaptcha.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import base64
2
+ import time
3
+
4
+ from selenium.webdriver.common.by import By
5
+ from selenium.webdriver.support.expected_conditions import presence_of_element_located, \
6
+ frame_to_be_available_and_switch_to_it
7
+ from selenium.webdriver.support.wait import WebDriverWait
8
+
9
+ from agency_swarm.tools import BaseTool
10
+ from .util import get_b64_screenshot, remove_highlight_and_labels
11
+ from .util.selenium import get_web_driver
12
+ from agency_swarm.util import get_openai_client
13
+
14
+
15
+ class SolveCaptcha(BaseTool):
16
+ """
17
+ This tool asks a human to solve captcha on the current webpage. Make sure that captcha is visible before running it.
18
+ """
19
+
20
+ def run(self):
21
+ wd = get_web_driver()
22
+
23
+ try:
24
+ WebDriverWait(wd, 10).until(
25
+ frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title='reCAPTCHA']"))
26
+ )
27
+
28
+ element = WebDriverWait(wd, 3).until(
29
+ presence_of_element_located((By.ID, "recaptcha-anchor"))
30
+ )
31
+ except Exception as e:
32
+ return "Could not find captcha checkbox"
33
+
34
+ try:
35
+ # Scroll the element into view
36
+ wd.execute_script("arguments[0].scrollIntoView(true);", element)
37
+ time.sleep(1) # Give some time for the scrolling to complete
38
+
39
+ # Click the element using JavaScript
40
+ wd.execute_script("arguments[0].click();", element)
41
+ except Exception as e:
42
+ return f"Could not click captcha checkbox: {str(e)}"
43
+
44
+ try:
45
+ # Now check if the reCAPTCHA is checked
46
+ WebDriverWait(wd, 3).until(
47
+ lambda d: d.find_element(By.CLASS_NAME, "recaptcha-checkbox").get_attribute(
48
+ "aria-checked") == "true"
49
+ )
50
+
51
+ return "Success"
52
+ except Exception as e:
53
+ pass
54
+
55
+ wd.switch_to.default_content()
56
+
57
+ client = get_openai_client()
58
+
59
+ WebDriverWait(wd, 10).until(
60
+ frame_to_be_available_and_switch_to_it(
61
+ (By.XPATH, "//iframe[@title='recaptcha challenge expires in two minutes']"))
62
+ )
63
+
64
+ time.sleep(2)
65
+
66
+ attempts = 0
67
+ while attempts < 5:
68
+ tiles = wd.find_elements(By.CLASS_NAME, "rc-imageselect-tile")
69
+
70
+ # filter out tiles with rc-imageselect-dynamic-selected class
71
+ tiles = [tile for tile in tiles if
72
+ not tile.get_attribute("class").endswith("rc-imageselect-dynamic-selected")]
73
+
74
+ image_content = []
75
+ i = 0
76
+ for tile in tiles:
77
+ i += 1
78
+ screenshot = get_b64_screenshot(wd, tile)
79
+
80
+ image_content.append(
81
+ {
82
+ "type": "text",
83
+ "text": f"Image {i}:",
84
+ }
85
+ )
86
+ image_content.append(
87
+ {
88
+ "type": "image_url",
89
+ "image_url":
90
+ {
91
+ "url": f"data:image/jpeg;base64,{screenshot}",
92
+ "detail": "high",
93
+ }
94
+ },
95
+ )
96
+ # highlight all titles with rc-imageselect-tile class but not with rc-imageselect-dynamic-selected
97
+ # wd = highlight_elements_with_labels(wd, 'td.rc-imageselect-tile:not(.rc-imageselect-dynamic-selected)')
98
+
99
+ # screenshot = get_b64_screenshot(wd, wd.find_element(By.ID, "rc-imageselect"))
100
+
101
+ task_text = wd.find_element(By.CLASS_NAME, "rc-imageselect-instructions").text.strip().replace("\n",
102
+ " ")
103
+
104
+ continuous_task = 'once there are none left' in task_text.lower()
105
+
106
+ task_text = task_text.replace("Click verify", "Output 0")
107
+ task_text = task_text.replace("click skip", "Output 0")
108
+ task_text = task_text.replace("once", "if")
109
+ task_text = task_text.replace("none left", "none")
110
+ task_text = task_text.replace("all", "only")
111
+ task_text = task_text.replace("squares", "images")
112
+
113
+ additional_info = ""
114
+ if len(tiles) > 9:
115
+ additional_info = ("Keep in mind that all images are a part of a bigger image "
116
+ "from left to right, and top to bottom. The grid is 4x4. ")
117
+
118
+ messages = [
119
+ {
120
+ "role": "system",
121
+ "content": f"""You are an advanced AI designed to support users with visual impairments.
122
+ User will provide you with {i} images numbered from 1 to {i}. Your task is to output
123
+ the numbers of the images that contain the requested object, or at least some part of the requested
124
+ object. {additional_info}If there are no individual images that satisfy this condition, output 0.
125
+ """.replace("\n", ""),
126
+ },
127
+ {
128
+ "role": "user",
129
+ "content": [
130
+ *image_content,
131
+ {
132
+ "type": "text",
133
+ "text": f"{task_text}. Only output numbers separated by commas and nothing else. "
134
+ f"Output 0 if there are none."
135
+ }
136
+ ]
137
+ }]
138
+
139
+ response = client.chat.completions.create(
140
+ model="gpt-4o",
141
+ messages=messages,
142
+ max_tokens=1024,
143
+ temperature=0.0,
144
+ )
145
+
146
+ message = response.choices[0].message
147
+ message_text = message.content
148
+
149
+ # check if 0 is in the message
150
+ if "0" in message_text and "10" not in message_text:
151
+ # Find the button by its ID
152
+ verify_button = wd.find_element(By.ID, "recaptcha-verify-button")
153
+
154
+ verify_button_text = verify_button.text
155
+
156
+ # Click the button
157
+ wd.execute_script("arguments[0].click();", verify_button)
158
+
159
+ time.sleep(1)
160
+
161
+ try:
162
+ if self.verify_checkbox(wd):
163
+ return "Success. Captcha solved."
164
+ except Exception as e:
165
+ print('Not checked')
166
+ pass
167
+
168
+ else:
169
+ numbers = [int(s.strip()) for s in message_text.split(",") if s.strip().isdigit()]
170
+
171
+ # Click the tiles based on the provided numbers
172
+ for number in numbers:
173
+ wd.execute_script("arguments[0].click();", tiles[number - 1])
174
+ time.sleep(0.5)
175
+
176
+ time.sleep(3)
177
+
178
+ if not continuous_task:
179
+ # Find the button by its ID
180
+ verify_button = wd.find_element(By.ID, "recaptcha-verify-button")
181
+
182
+ verify_button_text = verify_button.text
183
+
184
+ # Click the button
185
+ wd.execute_script("arguments[0].click();", verify_button)
186
+
187
+ try:
188
+ if self.verify_checkbox(wd):
189
+ return "Success. Captcha solved."
190
+ except Exception as e:
191
+ pass
192
+ else:
193
+ continue
194
+
195
+ if "verify" in verify_button_text.lower():
196
+ attempts += 1
197
+
198
+ wd = remove_highlight_and_labels(wd)
199
+
200
+ wd.switch_to.default_content()
201
+
202
+ # close captcha
203
+ try:
204
+ element = WebDriverWait(wd, 3).until(
205
+ presence_of_element_located((By.XPATH, "//iframe[@title='reCAPTCHA']"))
206
+ )
207
+
208
+ wd.execute_script(f"document.elementFromPoint({element.location['x']}, {element.location['y']-10}).click();")
209
+ except Exception as e:
210
+ print(e)
211
+ pass
212
+
213
+ return "Could not solve captcha."
214
+
215
+ def verify_checkbox(self, wd):
216
+ wd.switch_to.default_content()
217
+
218
+ try:
219
+ WebDriverWait(wd, 10).until(
220
+ frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title='reCAPTCHA']"))
221
+ )
222
+
223
+ WebDriverWait(wd, 5).until(
224
+ lambda d: d.find_element(By.CLASS_NAME, "recaptcha-checkbox").get_attribute(
225
+ "aria-checked") == "true"
226
+ )
227
+
228
+ return True
229
+ except Exception as e:
230
+ wd.switch_to.default_content()
231
+
232
+ WebDriverWait(wd, 10).until(
233
+ frame_to_be_available_and_switch_to_it(
234
+ (By.XPATH, "//iframe[@title='recaptcha challenge expires in two minutes']"))
235
+ )
236
+
237
+ return False
238
+
BrowsingAgent/tools/WebPageSummarizer.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from selenium.webdriver.common.by import By
2
+
3
+ from agency_swarm.tools import BaseTool
4
+ from .util import get_web_driver, set_web_driver
5
+
6
+
7
+ class WebPageSummarizer(BaseTool):
8
+ """
9
+ This tool summarizes the content of the current web page, extracting the main points and providing a concise summary.
10
+ """
11
+
12
+ def run(self):
13
+ from agency_swarm import get_openai_client
14
+
15
+ wd = get_web_driver()
16
+ client = get_openai_client()
17
+
18
+ content = wd.find_element(By.TAG_NAME, "body").text
19
+
20
+ # only use the first 10000 characters
21
+ content = " ".join(content.split()[:10000])
22
+
23
+ completion = client.chat.completions.create(
24
+ model="gpt-3.5-turbo",
25
+ messages=[
26
+ {"role": "system", "content": "Your task is to summarize the content of the provided webpage. The summary should be concise and informative, capturing the main points and takeaways of the page."},
27
+ {"role": "user", "content": "Summarize the content of the following webpage:\n\n" + content},
28
+ ],
29
+ temperature=0.0,
30
+ )
31
+
32
+ return completion.choices[0].message.content
33
+
34
+ if __name__ == "__main__":
35
+ wd = get_web_driver()
36
+ wd.get("https://en.wikipedia.org/wiki/Python_(programming_language)")
37
+ set_web_driver(wd)
38
+ tool = WebPageSummarizer()
39
+ print(tool.run())
BrowsingAgent/tools/__init__.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from .Scroll import Scroll
2
+ from .ReadURL import ReadURL
3
+ from .SendKeys import SendKeys
4
+ from .ClickElement import ClickElement
5
+ from .GoBack import GoBack
6
+ from .SelectDropdown import SelectDropdown
7
+ from .SolveCaptcha import SolveCaptcha
8
+ from .ExportFile import ExportFile
9
+ from .WebPageSummarizer import WebPageSummarizer
BrowsingAgent/tools/__pycache__/ClickElement.cpython-312.pyc ADDED
Binary file (3.4 kB). View file
 
BrowsingAgent/tools/__pycache__/ExportFile.cpython-312.pyc ADDED
Binary file (2.08 kB). View file
 
BrowsingAgent/tools/__pycache__/GoBack.cpython-312.pyc ADDED
Binary file (1.06 kB). View file
 
BrowsingAgent/tools/__pycache__/ReadURL.cpython-312.pyc ADDED
Binary file (2.61 kB). View file
 
BrowsingAgent/tools/__pycache__/Scroll.cpython-312.pyc ADDED
Binary file (2.4 kB). View file
 
BrowsingAgent/tools/__pycache__/SelectDropdown.cpython-312.pyc ADDED
Binary file (3.27 kB). View file
 
BrowsingAgent/tools/__pycache__/SendKeys.cpython-312.pyc ADDED
Binary file (4.14 kB). View file
 
BrowsingAgent/tools/__pycache__/SolveCaptcha.cpython-312.pyc ADDED
Binary file (9.36 kB). View file
 
BrowsingAgent/tools/__pycache__/WebPageSummarizer.cpython-312.pyc ADDED
Binary file (2.17 kB). View file
 
BrowsingAgent/tools/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (486 Bytes). View file
 
BrowsingAgent/tools/util/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .get_b64_screenshot import get_b64_screenshot
2
+ from .selenium import get_web_driver, set_web_driver
3
+ from .highlights import remove_highlight_and_labels, highlight_elements_with_labels
BrowsingAgent/tools/util/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (405 Bytes). View file
 
BrowsingAgent/tools/util/__pycache__/get_b64_screenshot.cpython-312.pyc ADDED
Binary file (489 Bytes). View file
 
BrowsingAgent/tools/util/__pycache__/highlights.cpython-312.pyc ADDED
Binary file (5.74 kB). View file
 
BrowsingAgent/tools/util/__pycache__/selenium.cpython-312.pyc ADDED
Binary file (7.38 kB). View file
 
BrowsingAgent/tools/util/get_b64_screenshot.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+
2
+ def get_b64_screenshot(wd, element=None):
3
+ if element:
4
+ screenshot_b64 = element.screenshot_as_base64
5
+ else:
6
+ screenshot_b64 = wd.get_screenshot_as_base64()
7
+
8
+ return screenshot_b64
BrowsingAgent/tools/util/highlights.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def highlight_elements_with_labels(driver, selector):
2
+ """
3
+ This function highlights clickable elements like buttons, links, and certain divs and spans
4
+ that match the given CSS selector on the webpage with a red border and ensures that labels are visible and positioned
5
+ correctly within the viewport.
6
+
7
+ :param driver: Instance of Selenium WebDriver.
8
+ :param selector: CSS selector for the elements to be highlighted.
9
+ """
10
+ script = f"""
11
+ // Helper function to check if an element is visible
12
+ function isElementVisible(element) {{
13
+ var rect = element.getBoundingClientRect();
14
+ if (rect.width <= 0 || rect.height <= 0 ||
15
+ rect.top >= (window.innerHeight || document.documentElement.clientHeight) ||
16
+ rect.bottom <= 0 ||
17
+ rect.left >= (window.innerWidth || document.documentElement.clientWidth) ||
18
+ rect.right <= 0) {{
19
+ return false;
20
+ }}
21
+ // Check if any parent element is hidden, which would hide this element as well
22
+ var parent = element;
23
+ while (parent) {{
24
+ var style = window.getComputedStyle(parent);
25
+ if (style.display === 'none' || style.visibility === 'hidden') {{
26
+ return false;
27
+ }}
28
+ parent = parent.parentElement;
29
+ }}
30
+ return true;
31
+ }}
32
+
33
+ // Remove previous labels and styles if they exist
34
+ document.querySelectorAll('.highlight-label').forEach(function(label) {{
35
+ label.remove();
36
+ }});
37
+ document.querySelectorAll('.highlighted-element').forEach(function(element) {{
38
+ element.classList.remove('highlighted-element');
39
+ element.removeAttribute('data-highlighted');
40
+ }});
41
+
42
+ // Inject custom style for highlighting elements
43
+ var styleElement = document.getElementById('highlight-style');
44
+ if (!styleElement) {{
45
+ styleElement = document.createElement('style');
46
+ styleElement.id = 'highlight-style';
47
+ document.head.appendChild(styleElement);
48
+ }}
49
+ styleElement.textContent = `
50
+ .highlighted-element {{
51
+ border: 2px solid red !important;
52
+ position: relative;
53
+ box-sizing: border-box;
54
+ }}
55
+ .highlight-label {{
56
+ position: absolute;
57
+ z-index: 2147483647;
58
+ background: yellow;
59
+ color: black;
60
+ font-size: 25px;
61
+ padding: 3px 5px;
62
+ border: 1px solid black;
63
+ border-radius: 3px;
64
+ white-space: nowrap;
65
+ box-shadow: 0px 0px 2px #000;
66
+ top: -25px;
67
+ left: 0;
68
+ display: none;
69
+ }}
70
+ `;
71
+
72
+ // Function to create and append a label to the body
73
+ function createAndAdjustLabel(element, index) {{
74
+ if (!isElementVisible(element)) return;
75
+
76
+ element.classList.add('highlighted-element');
77
+ var label = document.createElement('div');
78
+ label.className = 'highlight-label';
79
+ label.textContent = index.toString();
80
+ label.style.display = 'block'; // Make the label visible
81
+
82
+ // Calculate label position
83
+ var rect = element.getBoundingClientRect();
84
+ var top = rect.top + window.scrollY - 25; // Position label above the element
85
+ var left = rect.left + window.scrollX;
86
+
87
+ label.style.top = top + 'px';
88
+ label.style.left = left + 'px';
89
+
90
+ document.body.appendChild(label); // Append the label to the body
91
+ }}
92
+
93
+ // Select all clickable elements and apply the styles
94
+ var allElements = document.querySelectorAll('{selector}');
95
+ var index = 1;
96
+ allElements.forEach(function(element) {{
97
+ // Check if the element is not already highlighted and is visible
98
+ if (!element.dataset.highlighted && isElementVisible(element)) {{
99
+ element.dataset.highlighted = 'true';
100
+ createAndAdjustLabel(element, index++);
101
+ }}
102
+ }});
103
+ """
104
+
105
+ driver.execute_script(script)
106
+
107
+ return driver
108
+
109
+
110
+ def remove_highlight_and_labels(driver):
111
+ """
112
+ This function removes all red borders and labels from the webpage elements,
113
+ reversing the changes made by the highlight functions using Selenium WebDriver.
114
+
115
+ :param driver: Instance of Selenium WebDriver.
116
+ """
117
+ selector = ('a, button, input, textarea, div[onclick], div[role="button"], div[tabindex], span[onclick], '
118
+ 'span[role="button"], span[tabindex]')
119
+ script = f"""
120
+ // Remove all labels
121
+ document.querySelectorAll('.highlight-label').forEach(function(label) {{
122
+ label.remove();
123
+ }});
124
+
125
+ // Remove the added style for red borders
126
+ var highlightStyle = document.getElementById('highlight-style');
127
+ if (highlightStyle) {{
128
+ highlightStyle.remove();
129
+ }}
130
+
131
+ // Remove inline styles added by highlighting function
132
+ document.querySelectorAll('{selector}').forEach(function(element) {{
133
+ element.style.border = '';
134
+ }});
135
+ """
136
+
137
+ driver.execute_script(script)
138
+
139
+ return driver
BrowsingAgent/tools/util/selenium.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ wd = None
4
+
5
+ selenium_config = {
6
+ "chrome_profile_path": None,
7
+ "headless": True,
8
+ "full_page_screenshot": True,
9
+ }
10
+
11
+
12
+ def get_web_driver():
13
+ print("Initializing WebDriver...")
14
+ try:
15
+ from selenium import webdriver
16
+ from selenium.webdriver.chrome.service import Service as ChromeService
17
+ print("Selenium imported successfully.")
18
+ except ImportError:
19
+ print("Selenium not installed. Please install it with pip install selenium")
20
+ raise ImportError
21
+
22
+ try:
23
+ from webdriver_manager.chrome import ChromeDriverManager
24
+ print("webdriver_manager imported successfully.")
25
+ except ImportError:
26
+ print("webdriver_manager not installed. Please install it with pip install webdriver-manager")
27
+ raise ImportError
28
+
29
+ try:
30
+ from selenium_stealth import stealth
31
+ print("selenium_stealth imported successfully.")
32
+ except ImportError:
33
+ print("selenium_stealth not installed. Please install it with pip install selenium-stealth")
34
+ raise ImportError
35
+
36
+ global wd, selenium_config
37
+
38
+ if wd:
39
+ print("Returning existing WebDriver instance.")
40
+ return wd
41
+
42
+ chrome_profile_path = selenium_config.get("chrome_profile_path", None)
43
+ profile_directory = None
44
+ user_data_dir = None
45
+ if isinstance(chrome_profile_path, str) and os.path.exists(chrome_profile_path):
46
+ profile_directory = os.path.split(chrome_profile_path)[-1].strip("\\").rstrip("/")
47
+ user_data_dir = os.path.split(chrome_profile_path)[0].strip("\\").rstrip("/")
48
+ print(f"Using Chrome profile: {profile_directory}")
49
+ print(f"Using Chrome user data dir: {user_data_dir}")
50
+ print(f"Using Chrome profile path: {chrome_profile_path}")
51
+
52
+ chrome_options = webdriver.ChromeOptions()
53
+ print("ChromeOptions initialized.")
54
+
55
+ chrome_driver_path = "/usr/bin/chromedriver"
56
+ if not os.path.exists(chrome_driver_path):
57
+ print("ChromeDriver not found at /usr/bin/chromedriver. Installing using webdriver_manager.")
58
+ chrome_driver_path = ChromeDriverManager().install()
59
+ else:
60
+ print(f"ChromeDriver found at {chrome_driver_path}.")
61
+
62
+ if selenium_config.get("headless", False):
63
+ chrome_options.add_argument('--headless')
64
+ print("Headless mode enabled.")
65
+ if selenium_config.get("full_page_screenshot", False):
66
+ chrome_options.add_argument("--start-maximized")
67
+ print("Full page screenshot mode enabled.")
68
+ else:
69
+ chrome_options.add_argument("--window-size=1920,1080")
70
+ print("Window size set to 1920,1080.")
71
+
72
+ chrome_options.add_argument("--no-sandbox")
73
+ chrome_options.add_argument("--disable-gpu")
74
+ chrome_options.add_argument("--disable-dev-shm-usage")
75
+ chrome_options.add_argument("--remote-debugging-port=9222")
76
+ chrome_options.add_argument("--disable-extensions")
77
+ chrome_options.add_argument("--disable-popup-blocking")
78
+ chrome_options.add_argument("--ignore-certificate-errors")
79
+ chrome_options.add_argument("--disable-blink-features=AutomationControlled")
80
+ chrome_options.add_argument("--disable-web-security")
81
+ chrome_options.add_argument("--allow-running-insecure-content")
82
+ chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
83
+ chrome_options.add_experimental_option("useAutomationExtension", False)
84
+ print("Chrome options configured.")
85
+
86
+ if user_data_dir and profile_directory:
87
+ chrome_options.add_argument(f"user-data-dir={user_data_dir}")
88
+ chrome_options.add_argument(f"profile-directory={profile_directory}")
89
+ print(f"Using user data dir: {user_data_dir} and profile directory: {profile_directory}")
90
+
91
+ try:
92
+ wd = webdriver.Chrome(service=ChromeService(chrome_driver_path), options=chrome_options)
93
+ print("WebDriver initialized successfully.")
94
+ if wd.capabilities['chrome']['userDataDir']:
95
+ print(f"Profile path in use: {wd.capabilities['chrome']['userDataDir']}")
96
+ except Exception as e:
97
+ print(f"Error initializing WebDriver: {e}")
98
+ raise e
99
+
100
+ if not selenium_config.get("chrome_profile_path", None):
101
+ stealth(
102
+ wd,
103
+ languages=["en-US", "en"],
104
+ vendor="Google Inc.",
105
+ platform="Win32",
106
+ webgl_vendor="Intel Inc.",
107
+ renderer="Intel Iris OpenGL Engine",
108
+ fix_hairline=True,
109
+ )
110
+ print("Stealth mode configured.")
111
+
112
+ wd.implicitly_wait(3)
113
+ print("Implicit wait set to 3 seconds.")
114
+
115
+ return wd
116
+
117
+
118
+ def set_web_driver(new_wd):
119
+ # remove all popups
120
+ js_script = """
121
+ var popUpSelectors = ['modal', 'popup', 'overlay', 'dialog']; // Add more selectors that are commonly used for pop-ups
122
+ popUpSelectors.forEach(function(selector) {
123
+ var elements = document.querySelectorAll(selector);
124
+ elements.forEach(function(element) {
125
+ // You can choose to hide or remove; here we're removing the element
126
+ element.parentNode.removeChild(element);
127
+ });
128
+ });
129
+ """
130
+
131
+ new_wd.execute_script(js_script)
132
+
133
+ # Close LinkedIn specific popups
134
+ if "linkedin.com" in new_wd.current_url:
135
+ linkedin_js_script = """
136
+ var linkedinSelectors = ['div.msg-overlay-list-bubble', 'div.ml4.msg-overlay-list-bubble__tablet-height'];
137
+ linkedinSelectors.forEach(function(selector) {
138
+ var elements = document.querySelectorAll(selector);
139
+ elements.forEach(function(element) {
140
+ element.parentNode.removeChild(element);
141
+ });
142
+ });
143
+ """
144
+ new_wd.execute_script(linkedin_js_script)
145
+
146
+ new_wd.execute_script("document.body.style.zoom='1.2'")
147
+
148
+ global wd
149
+ wd = new_wd
150
+
151
+
152
+ def set_selenium_config(config):
153
+ global selenium_config
154
+ selenium_config = config
CompetitorTrackingAgent/CompetitorTrackingAgent.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agency_swarm.agents import Agent
2
+
3
+
4
+ class CompetitorTrackingAgent(Agent):
5
+ def __init__(self):
6
+ super().__init__(
7
+ name="CompetitorTrackingAgent",
8
+ description="This agent monitors competitors using web scraping tools like BeautifulSoup or Scrapy.",
9
+ instructions="./instructions.md",
10
+ files_folder="./files",
11
+ schemas_folder="./schemas",
12
+ tools=[],
13
+ tools_folder="./tools",
14
+ temperature=0.3,
15
+ max_prompt_tokens=25000,
16
+ )
17
+
18
+ def response_validator(self, message):
19
+ return message
CompetitorTrackingAgent/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .CompetitorTrackingAgent import CompetitorTrackingAgent
CompetitorTrackingAgent/__pycache__/CompetitorTrackingAgent.cpython-312.pyc ADDED
Binary file (1.16 kB). View file
 
CompetitorTrackingAgent/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (227 Bytes). View file
 
CompetitorTrackingAgent/instructions.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CompetitorTrackingAgent Instructions
2
+
3
+ You are an agent responsible for monitoring competitors by using web scraping tools like BeautifulSoup or Scrapy. You must ensure that the data collected is accurate and relevant to the agency's goals.
4
+
5
+ ### Primary Instructions:
6
+ 1. Identify competitor websites and online platforms that provide relevant information.
7
+ 2. Use web scraping tools like BeautifulSoup or Scrapy to extract data from these sources.
8
+ 3. Validate and clean the scraped data to ensure its accuracy and integrity.
9
+ 4. Store the collected data in a structured format that is accessible to other agents within the agency.
10
+ 5. Collaborate with other agents to provide them with the necessary data for their tasks.
11
+ 6. Monitor the competitor websites for any changes or updates and adjust the data collection process accordingly.
CompetitorTrackingAgent/tools/WebScrapingTool.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agency_swarm.tools import BaseTool
2
+ from pydantic import Field
3
+ import requests
4
+ from bs4 import BeautifulSoup
5
+
6
+ class WebScrapingTool(BaseTool):
7
+ """
8
+ A tool for performing web scraping tasks using BeautifulSoup.
9
+ This tool fetches a web page, parses the HTML content, and extracts specific data based on given criteria or tags.
10
+ """
11
+
12
+ url: str = Field(
13
+ ..., description="The URL of the web page to scrape."
14
+ )
15
+ tag: str = Field(
16
+ ..., description="The HTML tag to search for in the web page."
17
+ )
18
+ attribute: str = Field(
19
+ None, description="The attribute of the HTML tag to filter by, if any."
20
+ )
21
+ attribute_value: str = Field(
22
+ None, description="The value of the attribute to filter by, if any."
23
+ )
24
+
25
+ def run(self):
26
+ """
27
+ Fetches the web page, parses the HTML content, and extracts data based on the specified tag and attribute.
28
+ """
29
+ try:
30
+ # Make an HTTP request to fetch the web page
31
+ response = requests.get(self.url)
32
+ response.raise_for_status() # Raise an error for bad responses
33
+
34
+ # Parse the HTML content using BeautifulSoup
35
+ soup = BeautifulSoup(response.content, 'html.parser')
36
+
37
+ # Find all elements matching the specified tag and attribute
38
+ if self.attribute and self.attribute_value:
39
+ elements = soup.find_all(self.tag, {self.attribute: self.attribute_value})
40
+ else:
41
+ elements = soup.find_all(self.tag)
42
+
43
+ # Extract and return the text content of the found elements
44
+ extracted_data = [element.get_text(strip=True) for element in elements]
45
+ return extracted_data
46
+
47
+ except requests.RequestException as e:
48
+ return f"An error occurred while fetching the web page: {e}"
49
+ except Exception as e:
50
+ return f"An error occurred during parsing or extraction: {e}"
51
+
52
+ if __name__ == "__main__":
53
+ tool = WebScrapingTool(
54
+ url="https://example.com",
55
+ tag="p",
56
+ attribute="class",
57
+ attribute_value="content"
58
+ )
59
+ print(tool.run())
CompetitorTrackingAgent/tools/__pycache__/WebScrapingTool.cpython-312.pyc ADDED
Binary file (2.85 kB). View file
 
DataAnalystAgent/DataAnalystAgent.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agency_swarm.agents import Agent
2
+ from agency_swarm.tools import CodeInterpreter
3
+
4
+ class DataAnalystAgent(Agent):
5
+ def __init__(self):
6
+ super().__init__(
7
+ name="DataAnalystAgent",
8
+ description="This agent analyzes the collected data to identify trends, opportunities, and insights.",
9
+ instructions="./instructions.md",
10
+ files_folder="./files",
11
+ schemas_folder="./schemas",
12
+ tools=[CodeInterpreter],
13
+ tools_folder="./tools",
14
+ temperature=0.3,
15
+ max_prompt_tokens=25000,
16
+ )
17
+
18
+ def response_validator(self, message):
19
+ return message
DataAnalystAgent/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .DataAnalystAgent import DataAnalystAgent
DataAnalystAgent/__pycache__/DataAnalystAgent.cpython-312.pyc ADDED
Binary file (1.2 kB). View file
 
DataAnalystAgent/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (213 Bytes). View file
 
DataAnalystAgent/instructions.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DataAnalystAgent Instructions
2
+
3
+ You are an agent responsible for analyzing the collected market data to identify trends, opportunities, and insights. You must use data analysis tools and libraries like Pandas and NumPy to perform your tasks effectively.
4
+
5
+ ### Primary Instructions:
6
+ 1. Access the structured data collected by the DataCollectorAgent.
7
+ 2. Use data analysis libraries such as Pandas and NumPy to process and analyze the data.
8
+ 3. Identify trends, patterns, and anomalies in the data that could provide valuable insights.
9
+ 4. Generate reports and visualizations to communicate your findings to other agents and clients.
10
+ 5. Collaborate with other agents to ensure your analysis aligns with the agency's goals and objectives.
11
+ 6. Continuously update your analysis based on new data and feedback from clients and stakeholders.
DataAnalystAgent/tools/DataAnalysisTool.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agency_swarm.tools import BaseTool
2
+ from pydantic import Field
3
+ import pandas as pd
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ import seaborn as sns
7
+ import io
8
+
9
+ class DataAnalysisTool(BaseTool):
10
+ """
11
+ This tool utilizes data analysis libraries such as Pandas and NumPy to process and analyze structured data.
12
+ It is capable of identifying trends, patterns, and anomalies in the data.
13
+ The tool also generates reports and visualizations to communicate findings.
14
+ """
15
+
16
+ data: str = Field(
17
+ ..., description="The structured data in CSV format to be analyzed."
18
+ )
19
+
20
+ def run(self):
21
+ """
22
+ Processes and analyzes the provided structured data.
23
+ Identifies trends, patterns, and anomalies, and generates reports and visualizations.
24
+ """
25
+ # Load data into a Pandas DataFrame
26
+ data_io = io.StringIO(self.data)
27
+ df = pd.read_csv(data_io)
28
+
29
+ # Perform basic data analysis
30
+ summary = self._generate_summary(df)
31
+ trends = self._identify_trends(df)
32
+ anomalies = self._detect_anomalies(df)
33
+
34
+ # Generate visualizations
35
+ visualizations = self._generate_visualizations(df)
36
+
37
+ # Compile the report
38
+ report = {
39
+ "summary": summary,
40
+ "trends": trends,
41
+ "anomalies": anomalies,
42
+ "visualizations": visualizations
43
+ }
44
+
45
+ return report
46
+
47
+ def _generate_summary(self, df):
48
+ """
49
+ Generates a summary of the data including basic statistics.
50
+ """
51
+ summary = df.describe().to_dict()
52
+ return summary
53
+
54
+ def _identify_trends(self, df):
55
+ """
56
+ Identifies trends in the data using rolling averages.
57
+ """
58
+ trends = {}
59
+ for column in df.select_dtypes(include=[np.number]).columns:
60
+ trends[column] = df[column].rolling(window=5).mean().dropna().tolist()
61
+ return trends
62
+
63
+ def _detect_anomalies(self, df):
64
+ """
65
+ Detects anomalies in the data using z-score method.
66
+ """
67
+ anomalies = {}
68
+ for column in df.select_dtypes(include=[np.number]).columns:
69
+ z_scores = np.abs((df[column] - df[column].mean()) / df[column].std())
70
+ anomalies[column] = df[column][z_scores > 3].tolist()
71
+ return anomalies
72
+
73
+ def _generate_visualizations(self, df):
74
+ """
75
+ Generates visualizations for the data.
76
+ """
77
+ visualizations = {}
78
+ for column in df.select_dtypes(include=[np.number]).columns:
79
+ plt.figure(figsize=(10, 6))
80
+ sns.lineplot(data=df, x=df.index, y=column)
81
+ plt.title(f'Trend for {column}')
82
+ plt.xlabel('Index')
83
+ plt.ylabel(column)
84
+ buf = io.BytesIO()
85
+ plt.savefig(buf, format='png')
86
+ buf.seek(0)
87
+ visualizations[column] = buf.getvalue()
88
+ plt.close()
89
+ return visualizations