Skip to content

Commit

Permalink
Plugins initial
Browse files Browse the repository at this point in the history
  • Loading branch information
BillSchumacher committed Apr 11, 2023
1 parent e62a3be commit 65b626c
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 2 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,17 @@ export PINECONE_ENV="Your pinecone region" # something like: us-east4-gcp
```

## Plugins

See https://github.com/Torantulino/Auto-GPT-Plugin-Template for the template of the plugins.

WARNING: Review the code of any plugin you use.

Drop the repo's zipfile in the plugins folder.

![Download Zip](https://raw.githubusercontent.com/BillSchumacher/Auto-GPT/master/plugin.png)

If you add the plugins class name to the whitelist in the config.py you will not be prompted otherwise you'll be warned before loading the plugin.

## View Memory Usage

Expand Down
Binary file added plugin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
8 changes: 8 additions & 0 deletions scripts/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ def __init__(self):
# Initialize the OpenAI API client
openai.api_key = self.openai_api_key

self.plugins = []
self.plugins_whitelist = []
self.plugins_blacklist = []

def set_continuous_mode(self, value: bool):
"""Set the continuous mode value."""
self.continuous_mode = value
Expand Down Expand Up @@ -135,3 +139,7 @@ def set_pinecone_region(self, value: str):
def set_debug_mode(self, value: bool):
"""Set the debug mode value."""
self.debug = value

def set_plugins(self, value: list):
"""Set the plugins value."""
self.plugins = value
6 changes: 4 additions & 2 deletions scripts/llm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ def create_chat_completion(messages, model=None, temperature=None, max_tokens=No
temperature=temperature,
max_tokens=max_tokens
)

return response.choices[0].message["content"]
resp = response.choices[0].message["content"]
for plugin in cfg.plugins:
resp = plugin.on_response(resp)
return resp
27 changes: 27 additions & 0 deletions scripts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
import sys
from config import Config
from json_parser import fix_and_parse_json
from plugins import load_plugins
from ai_config import AIConfig
import os
from pathlib import Path
import traceback
import yaml
import argparse
Expand Down Expand Up @@ -323,6 +326,30 @@ def parse_arguments():
memory = get_memory(cfg, init=True)
print('Using memory of type: ' + memory.__class__.__name__)


plugins_found = load_plugins(Path(os.getcwd()) / "plugins")
loaded_plugins = []
for plugin in plugins_found:
if plugin.__name__ in cfg.plugins_blacklist:
continue
if plugin.__name__ in cfg.plugins_whitelist:
loaded_plugins.append(plugin())
else:
ack = input(
f"WARNNG Plugin {plugin.__name__} found. But not in the"
" whitelist... Load? (y/n): "
)
if ack.lower() == "y":
loaded_plugins.append(plugin())

if loaded_plugins:
print(f"\nPlugins found: {len(loaded_plugins)}\n"
"--------------------")
for plugin in loaded_plugins:
print(f"{plugin._name}: {plugin._version} - {plugin._description}")

cfg.set_plugins(loaded_plugins)

# Interaction Loop
while True:
# Send message to AI, get response
Expand Down
74 changes: 74 additions & 0 deletions scripts/plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Handles loading of plugins."""

from ast import Module
import zipfile
from pathlib import Path
from zipimport import zipimporter
from typing import List, Optional, Tuple


def inspect_zip_for_module(zip_path: str, debug: bool = False) -> Optional[str]:
"""
Inspect a zipfile for a module.
Args:
zip_path (str): Path to the zipfile.
debug (bool, optional): Enable debug logging. Defaults to False.
Returns:
Optional[str]: The name of the module if found, else None.
"""
with zipfile.ZipFile(zip_path, 'r') as zfile:
for name in zfile.namelist():
if name.endswith("__init__.py"):
if debug:
print(f"Found module '{name}' in the zipfile at: {name}")
return name
if debug:
print(f"Module '__init__.py' not found in the zipfile @ {zip_path}.")
return None


def scan_plugins(plugins_path: Path, debug: bool = False) -> List[Tuple[str, Path]]:
"""Scan the plugins directory for plugins.
Args:
plugins_path (Path): Path to the plugins directory.
Returns:
List[Path]: List of plugins.
"""
plugins = []
for plugin in plugins_path.glob("*.zip"):
if module := inspect_zip_for_module(str(plugin), debug):
plugins.append((module, plugin))
return plugins


def load_plugins(plugins_path: Path, debug: bool = False) -> List[Module]:
"""Load plugins from the plugins directory.
Args:
plugins_path (Path): Path to the plugins directory.
Returns:
List[Path]: List of plugins.
"""
plugins = scan_plugins(plugins_path)
plugin_modules = []
for module, plugin in plugins:
plugin = Path(plugin)
module = Path(module)
if debug:
print(f"Plugin: {plugin} Module: {module}")
zipped_package = zipimporter(plugin)
zipped_module = zipped_package.load_module(str(module.parent))
for key in dir(zipped_module):
if key.startswith("__"):
continue
a_module = getattr(zipped_module, key)
a_keys = dir(a_module)
if '_abc_impl' in a_keys and \
a_module.__name__ != 'AutoGPTPluginTemplate':
plugin_modules.append(a_module)
return plugin_modules

0 comments on commit 65b626c

Please sign in to comment.