Vector memory revamp (part 1: refactoring) (#4208)

Additional changes:

* Improve typing

* Modularize message history memory & fix/refactor lots of things

* Fix summarization

* Move memory relevance calculation to MemoryItem & improve test

* Fix import warnings in web_selenium.py

* Remove `memory_add` ghost command

* Implement overlap in `split_text`

* Move memory tests into subdirectory

* Remove deprecated `get_ada_embedding()` and helpers

* Fix used token calculation in `chat_with_ai`

* Replace Message TypedDict by dataclass

* Fix AgentManager singleton issues in tests

---------

Co-authored-by: Auto-GPT-Bot <github-bot@agpt.co>
This commit is contained in:
Reinier van der Leer
2023-05-25 20:31:11 +02:00
committed by GitHub
parent 10489e0df2
commit bfbe613960
92 changed files with 7282 additions and 7989 deletions

View File

@@ -4,28 +4,39 @@ from __future__ import annotations
import logging
from pathlib import Path
from sys import platform
from typing import Optional, Type
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.chrome.service import Service as ChromeDriverService
from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options as EdgeOptions
from selenium.webdriver.edge.service import Service as EdgeDriverService
from selenium.webdriver.edge.webdriver import WebDriver as EdgeDriver
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.firefox.service import Service as GeckoDriverService
from selenium.webdriver.firefox.webdriver import WebDriver as FirefoxDriver
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.safari.options import Options as SafariOptions
from selenium.webdriver.safari.webdriver import WebDriver as SafariDriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.firefox import GeckoDriverManager
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from webdriver_manager.microsoft import EdgeChromiumDriverManager as EdgeDriverManager
import autogpt.processing.text as summary
from autogpt.commands.command import command
from autogpt.config import Config
from autogpt.logs import logger
from autogpt.memory.vector import MemoryItem, NoMemory, get_memory
from autogpt.processing.html import extract_hyperlinks, format_hyperlinks
from autogpt.processing.text import summarize_text
from autogpt.url_utils.validators import validate_url
BrowserOptions = ChromeOptions | EdgeOptions | FirefoxOptions | SafariOptions
FILE_DIR = Path(__file__).parent.parent
CFG = Config()
@@ -55,14 +66,14 @@ def browse_website(url: str, question: str) -> str:
return f"Error: {msg}"
add_header(driver)
summary_text = summary.summarize_text(url, text, question, driver)
summary = summarize_memorize_webpage(url, text, question, driver)
links = scrape_links_with_selenium(driver, url)
# Limit links to 5
if len(links) > 5:
links = links[:5]
close_browser(driver)
return f"Answer gathered from website: {summary_text} \n \n Links: {links}"
return f"Answer gathered from website: {summary}\n\nLinks: {links}"
def scrape_text_with_selenium(url: str) -> tuple[WebDriver, str]:
@@ -76,14 +87,14 @@ def scrape_text_with_selenium(url: str) -> tuple[WebDriver, str]:
"""
logging.getLogger("selenium").setLevel(logging.CRITICAL)
options_available = {
options_available: dict[str, Type[BrowserOptions]] = {
"chrome": ChromeOptions,
"safari": SafariOptions,
"firefox": FirefoxOptions,
"edge": EdgeOptions,
"firefox": FirefoxOptions,
"safari": SafariOptions,
}
options = options_available[CFG.selenium_web_browser]()
options: BrowserOptions = options_available[CFG.selenium_web_browser]()
options.add_argument(
"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.49 Safari/537.36"
)
@@ -92,17 +103,17 @@ def scrape_text_with_selenium(url: str) -> tuple[WebDriver, str]:
if CFG.selenium_headless:
options.headless = True
options.add_argument("--disable-gpu")
driver = webdriver.Firefox(
executable_path=GeckoDriverManager().install(), options=options
driver = FirefoxDriver(
service=GeckoDriverService(GeckoDriverManager().install()), options=options
)
elif CFG.selenium_web_browser == "edge":
driver = EdgeDriver(
service=EdgeDriverService(EdgeDriverManager().install()), options=options
)
elif CFG.selenium_web_browser == "safari":
# Requires a bit more setup on the users end
# See https://developer.apple.com/documentation/webkit/testing_with_webdriver_in_safari
driver = webdriver.Safari(options=options)
elif CFG.selenium_web_browser == "edge":
driver = webdriver.Edge(
executable_path=EdgeChromiumDriverManager().install(), options=options
)
driver = SafariDriver(options=options)
else:
if platform == "linux" or platform == "linux2":
options.add_argument("--disable-dev-shm-usage")
@@ -115,10 +126,10 @@ def scrape_text_with_selenium(url: str) -> tuple[WebDriver, str]:
chromium_driver_path = Path("/usr/bin/chromedriver")
driver = webdriver.Chrome(
executable_path=chromium_driver_path
driver = ChromeDriver(
service=ChromeDriverService(str(chromium_driver_path))
if chromium_driver_path.exists()
else ChromeDriverManager().install(),
else ChromeDriverService(ChromeDriverManager().install()),
options=options,
)
driver.get(url)
@@ -188,3 +199,30 @@ def add_header(driver: WebDriver) -> None:
driver.execute_script(overlay_script)
except Exception as e:
print(f"Error executing overlay.js: {e}")
def summarize_memorize_webpage(
url: str, text: str, question: str, driver: Optional[WebDriver] = None
) -> str:
"""Summarize text using the OpenAI API
Args:
url (str): The url of the text
text (str): The text to summarize
question (str): The question to ask the model
driver (WebDriver): The webdriver to use to scroll the page
Returns:
str: The summary of the text
"""
if not text:
return "Error: No text to summarize"
text_length = len(text)
logger.info(f"Text length: {text_length} characters")
memory = get_memory(CFG)
new_memory = MemoryItem.from_webpage(text, url, question=question)
memory.add(new_memory)
return new_memory.summary