Date: Mon, 17 Apr 2023 03:21:46 +0200
Subject: [PATCH 09/14] Add Get Help header in README
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 07a088e3..e2b3b4d2 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@
[](https://github.com/Significant-Gravitas/Auto-GPT/stargazers)
[](https://twitter.com/SigGravitas)
+## π‘ Get help - [Q&A](https://github.com/Significant-Gravitas/Auto-GPT/discussions/categories/q-a) or [Discord π¬](https://discord.gg/autogpt)
From 9ffa587f6f1c96c76f82a55ae3d18aead5ff0b9a Mon Sep 17 00:00:00 2001
From: Void&Null <70048414+Void-n-Null@users.noreply.github.com>
Date: Sun, 16 Apr 2023 17:39:03 -0700
Subject: [PATCH 10/14] Implement new demo video into read me
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index e2b3b4d2..7154801e 100644
--- a/README.md
+++ b/README.md
@@ -18,9 +18,9 @@ The `master` branch may often be in a **broken** state.
Auto-GPT is an experimental open-source application showcasing the capabilities of the GPT-4 language model. This program, driven by GPT-4, chains together LLM "thoughts", to autonomously achieve whatever goal you set. As one of the first examples of GPT-4 running fully autonomously, Auto-GPT pushes the boundaries of what is possible with AI.
-### Demo (30/03/2023):
+ Demo April 16th 2023
-https://user-images.githubusercontent.com/22963551/228855501-2f5777cf-755b-4407-a643-c7299e5b6419.mp4
+https://user-images.githubusercontent.com/70048414/232352935-55c6bf7c-3958-406e-8610-0913475a0b05.mp4
π Help Fund Auto-GPT's Development π
From 1d4dc0c534cc7ef585f760f9eaf7293134bba282 Mon Sep 17 00:00:00 2001
From: "xuqi.wxq"
Date: Mon, 17 Apr 2023 10:17:26 +0800
Subject: [PATCH 11/14] Fix milvus test Error: 'NameError: name 'MockConfig' is
not defined'
---
tests/milvus_memory_test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/milvus_memory_test.py b/tests/milvus_memory_test.py
index e0e2f7fc..84fd6e6d 100644
--- a/tests/milvus_memory_test.py
+++ b/tests/milvus_memory_test.py
@@ -26,7 +26,7 @@ try:
def setUp(self) -> None:
"""Set up the test environment"""
- self.cfg = MockConfig()
+ self.cfg = mock_config()
self.memory = MilvusMemory(self.cfg)
def test_add(self) -> None:
From 0409079983542a7babc50b1b0fd28a7a506b7019 Mon Sep 17 00:00:00 2001
From: Void&Null <70048414+Void-n-Null@users.noreply.github.com>
Date: Sun, 16 Apr 2023 19:27:39 -0700
Subject: [PATCH 12/14] Added Credit to README.md Demo
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 7154801e..71957748 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,8 @@ Auto-GPT is an experimental open-source application showcasing the capabilities
https://user-images.githubusercontent.com/70048414/232352935-55c6bf7c-3958-406e-8610-0913475a0b05.mp4
+Demo made by Blake Werlinger
+
π Help Fund Auto-GPT's Development π
If you can spare a coffee, you can help to cover the costs of developing Auto-GPT and help push the boundaries of fully autonomous AI!
From 9589334a305198c837bfb8720ed6f06176b2f216 Mon Sep 17 00:00:00 2001
From: EH
Date: Mon, 17 Apr 2023 03:34:02 +0100
Subject: [PATCH 13/14] Add File Downloading Capabilities (#1680)
* Added 'download_file' command
* Added util and fixed spinner
* Fixed comma and added autogpt/auto_gpt_workspace to .gitignore
* Fix linter issues
* Fix more linter issues
* Fix Lint Issues
* Added 'download_file' command
* Added util and fixed spinner
* Fixed comma and added autogpt/auto_gpt_workspace to .gitignore
* Fix linter issues
* Fix more linter issues
* Conditionally add the 'download_file' prompt
* Update args.py
* Removed Duplicate Prompt
* Switched to using path_in_workspace function
---
.gitignore | 1 +
autogpt/app.py | 5 +++
autogpt/args.py | 16 +++++++++-
autogpt/commands/file_operations.py | 49 ++++++++++++++++++++++++++++-
autogpt/config/config.py | 1 +
autogpt/prompt.py | 10 ++++++
autogpt/spinner.py | 15 ++++++++-
autogpt/utils.py | 13 ++++++++
8 files changed, 107 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index eda7f327..2220ef6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ autogpt/keys.py
autogpt/*json
autogpt/node_modules/
autogpt/__pycache__/keys.cpython-310.pyc
+autogpt/auto_gpt_workspace
package-lock.json
*.pyc
auto_gpt_workspace/*
diff --git a/autogpt/app.py b/autogpt/app.py
index 78b5bd2f..19c075f0 100644
--- a/autogpt/app.py
+++ b/autogpt/app.py
@@ -17,6 +17,7 @@ from autogpt.commands.file_operations import (
read_file,
search_files,
write_to_file,
+ download_file
)
from autogpt.json_fixes.parsing import fix_and_parse_json
from autogpt.memory import get_memory
@@ -164,6 +165,10 @@ def execute_command(command_name: str, arguments):
return delete_file(arguments["file"])
elif command_name == "search_files":
return search_files(arguments["directory"])
+ elif command_name == "download_file":
+ if not CFG.allow_downloads:
+ return "Error: You do not have user authorization to download files locally."
+ return download_file(arguments["url"], arguments["file"])
elif command_name == "browse_website":
return browse_website(arguments["url"], arguments["question"])
# TODO: Change these to take in a file rather than pasted code, if
diff --git a/autogpt/args.py b/autogpt/args.py
index eca32334..f0e9c07a 100644
--- a/autogpt/args.py
+++ b/autogpt/args.py
@@ -1,7 +1,7 @@
"""This module contains the argument parsing logic for the script."""
import argparse
-from colorama import Fore
+from colorama import Fore, Back, Style
from autogpt import utils
from autogpt.config import Config
from autogpt.logs import logger
@@ -63,6 +63,12 @@ def parse_arguments() -> None:
help="Specifies which ai_settings.yaml file to use, will also automatically"
" skip the re-prompt.",
)
+ parser.add_argument(
+ '--allow-downloads',
+ action='store_true',
+ dest='allow_downloads',
+ help='Dangerous: Allows Auto-GPT to download files natively.'
+ )
args = parser.parse_args()
if args.debug:
@@ -133,5 +139,13 @@ def parse_arguments() -> None:
CFG.ai_settings_file = file
CFG.skip_reprompt = True
+ if args.allow_downloads:
+ logger.typewriter_log("Native Downloading:", Fore.GREEN, "ENABLED")
+ logger.typewriter_log("WARNING: ", Fore.YELLOW,
+ f"{Back.LIGHTYELLOW_EX}Auto-GPT will now be able to download and save files to your machine.{Back.RESET} " +
+ "It is recommended that you monitor any files it downloads carefully.")
+ logger.typewriter_log("WARNING: ", Fore.YELLOW, f"{Back.RED + Style.BRIGHT}ALWAYS REMEMBER TO NEVER OPEN FILES YOU AREN'T SURE OF!{Style.RESET_ALL}")
+ CFG.allow_downloads = True
+
if args.browser_name:
CFG.selenium_web_browser = args.browser_name
diff --git a/autogpt/commands/file_operations.py b/autogpt/commands/file_operations.py
index 8abc2e23..d273c1a3 100644
--- a/autogpt/commands/file_operations.py
+++ b/autogpt/commands/file_operations.py
@@ -4,9 +4,16 @@ from __future__ import annotations
import os
import os.path
from pathlib import Path
-from typing import Generator
+from typing import Generator, List
+import requests
+from requests.adapters import HTTPAdapter
+from requests.adapters import Retry
+from colorama import Fore, Back
+from autogpt.spinner import Spinner
+from autogpt.utils import readable_file_size
from autogpt.workspace import path_in_workspace, WORKSPACE_PATH
+
LOG_FILE = "file_logger.txt"
LOG_FILE_PATH = WORKSPACE_PATH / LOG_FILE
@@ -214,3 +221,43 @@ def search_files(directory: str) -> list[str]:
found_files.append(relative_path)
return found_files
+
+
+def download_file(url, filename):
+ """Downloads a file
+ Args:
+ url (str): URL of the file to download
+ filename (str): Filename to save the file as
+ """
+ safe_filename = path_in_workspace(filename)
+ try:
+ message = f"{Fore.YELLOW}Downloading file from {Back.LIGHTBLUE_EX}{url}{Back.RESET}{Fore.RESET}"
+ with Spinner(message) as spinner:
+ session = requests.Session()
+ retry = Retry(total=3, backoff_factor=1, status_forcelist=[502, 503, 504])
+ adapter = HTTPAdapter(max_retries=retry)
+ session.mount('http://', adapter)
+ session.mount('https://', adapter)
+
+ total_size = 0
+ downloaded_size = 0
+
+ with session.get(url, allow_redirects=True, stream=True) as r:
+ r.raise_for_status()
+ total_size = int(r.headers.get('Content-Length', 0))
+ downloaded_size = 0
+
+ with open(safe_filename, 'wb') as f:
+ for chunk in r.iter_content(chunk_size=8192):
+ f.write(chunk)
+ downloaded_size += len(chunk)
+
+ # Update the progress message
+ progress = f"{readable_file_size(downloaded_size)} / {readable_file_size(total_size)}"
+ spinner.update_message(f"{message} {progress}")
+
+ return f'Successfully downloaded and locally stored file: "{filename}"! (Size: {readable_file_size(total_size)})'
+ except requests.HTTPError as e:
+ return f"Got an HTTP Error whilst trying to download file: {e}"
+ except Exception as e:
+ return "Error: " + str(e)
diff --git a/autogpt/config/config.py b/autogpt/config/config.py
index 22da52b0..fe6f4f32 100644
--- a/autogpt/config/config.py
+++ b/autogpt/config/config.py
@@ -24,6 +24,7 @@ class Config(metaclass=Singleton):
self.continuous_limit = 0
self.speak_mode = False
self.skip_reprompt = False
+ self.allow_downloads = False
self.selenium_web_browser = os.getenv("USE_WEB_BROWSER", "chrome")
self.ai_settings_file = os.getenv("AI_SETTINGS_FILE", "ai_settings.yaml")
diff --git a/autogpt/prompt.py b/autogpt/prompt.py
index 18a5736c..a2b20b1f 100644
--- a/autogpt/prompt.py
+++ b/autogpt/prompt.py
@@ -105,6 +105,16 @@ def get_prompt() -> str:
),
)
+ # Only add the download file command if the AI is allowed to execute it
+ if cfg.allow_downloads:
+ commands.append(
+ (
+ "Downloads a file from the internet, and stores it locally",
+ "download_file",
+ {"url": "", "file": ""}
+ ),
+ )
+
# Add these command last.
commands.append(
("Do Nothing", "do_nothing", {}),
diff --git a/autogpt/spinner.py b/autogpt/spinner.py
index 56b4f20a..febcea8e 100644
--- a/autogpt/spinner.py
+++ b/autogpt/spinner.py
@@ -29,12 +29,14 @@ class Spinner:
time.sleep(self.delay)
sys.stdout.write(f"\r{' ' * (len(self.message) + 2)}\r")
- def __enter__(self) -> None:
+ def __enter__(self):
"""Start the spinner"""
self.running = True
self.spinner_thread = threading.Thread(target=self.spin)
self.spinner_thread.start()
+ return self
+
def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
"""Stop the spinner
@@ -48,3 +50,14 @@ class Spinner:
self.spinner_thread.join()
sys.stdout.write(f"\r{' ' * (len(self.message) + 2)}\r")
sys.stdout.flush()
+
+ def update_message(self, new_message, delay=0.1):
+ """Update the spinner message
+ Args:
+ new_message (str): New message to display
+ delay: Delay in seconds before updating the message
+ """
+ time.sleep(delay)
+ sys.stdout.write(f"\r{' ' * (len(self.message) + 2)}\r") # Clear the current message
+ sys.stdout.flush()
+ self.message = new_message
diff --git a/autogpt/utils.py b/autogpt/utils.py
index 59709d02..11d98d1b 100644
--- a/autogpt/utils.py
+++ b/autogpt/utils.py
@@ -24,3 +24,16 @@ def validate_yaml_file(file: str):
)
return (True, f"Successfully validated {Fore.CYAN}`{file}`{Fore.RESET}!")
+
+
+def readable_file_size(size, decimal_places=2):
+ """Converts the given size in bytes to a readable format.
+ Args:
+ size: Size in bytes
+ decimal_places (int): Number of decimal places to display
+ """
+ for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
+ if size < 1024.0:
+ break
+ size /= 1024.0
+ return f"{size:.{decimal_places}f} {unit}"
From 0fa807394711010a17fe37a3afbce81978e233e2 Mon Sep 17 00:00:00 2001
From: Ben Song
Date: Mon, 17 Apr 2023 11:53:05 +0800
Subject: [PATCH 14/14] add docker requirements - jsonschema
---
requirements-docker.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/requirements-docker.txt b/requirements-docker.txt
index 3a8a344c..a6018f8f 100644
--- a/requirements-docker.txt
+++ b/requirements-docker.txt
@@ -24,4 +24,5 @@ pre-commit
black
isort
gitpython==3.1.31
-tweepy
\ No newline at end of file
+tweepy
+jsonschema
\ No newline at end of file