Repository: Significant-Gravitas/AutoGPT
Pull request: Only take subclasses of AutoGPTPluginTemplate as plugins
this fixes #4215, and is a re-submission of #4217 where i managed to screw up the history of the PR.

### Background
limit plugin detection to classes that implement  AutoGPTPluginTemplate (have it as parent), 
solving #4215 

### Changes
added check to scan_plugin 

### Test Plan
create empty plugin, add class triggering old detection -> run = only real plugins detected

### PR Quality Checklist
- [x] My pull request is atomic and focuses on a single change.
- [x] I have thoroughly tested my changes with multiple different prompts.
- [x] I have considered potential risks and mitigations for my changes.
- [x] I have documented my changes clearly and comprehensively.
- [x] I have not snuck in any "extra" small tweaks changes 


Problem statement:
scan_plugin currently will assume any class that has an _abc_impl is a plugin
### ⚠️ Search for existing issues first ⚠️

- [X] I have searched the existing issues, and there is no existing issue for my problem

### Which Operating System are you using?

Docker

### Which version of Auto-GPT are you using?

Master (branch)

### GPT-3 or GPT-4?

GPT-4

### Steps to reproduce 🕹

* create a plugin, include a file like
```python
from typing import Protocol


class Example(Protocol):
    def example_method(self) -> None:
        pass


class NotAPlugin(Example):
    def example_method(self):
        print("foo")
```

### Current behavior 😯

when loading plugins the class is recognized as a plugin, a prompt appears:
`WARNING: Plugin NotAPlugin found. But not in the allowlist... Load? (y/n):`

### Expected behavior 🤔

class is not confused for a plugin

### Your prompt 📝

not applicable

### Your Logs 📒

WARNING: Plugin AutoGPTExamplePlugin found. But not in the allowlist... Load? (y/n): y
WARNING: Plugin NotAPlugin found. But not in the allowlist... Load? (y/n):

Hints from issue discussion:

Commit message: Black formatting

Patch to review:
diff --git a/.gitignore b/.gitignore
index 29a0285a86b1..1376ba5dd7c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,7 +31,7 @@ __pycache__/
 build/
 develop-eggs/
 dist/
-plugins/
+/plugins/
 plugins_config.yaml
 downloads/
 eggs/
diff --git a/autogpt/plugins/__init__.py b/autogpt/plugins/__init__.py
index d0a4864c5926..5b99bf144dec 100644
--- a/autogpt/plugins/__init__.py
+++ b/autogpt/plugins/__init__.py
@@ -260,10 +260,15 @@ def scan_plugins(config: Config, debug: bool = False) -> List[AutoGPTPluginTempl
                         continue
                     a_module = getattr(zipped_module, key)
                     a_keys = dir(a_module)
-                    if (
-                        "_abc_impl" in a_keys
-                        and a_module.__name__ != "AutoGPTPluginTemplate"
-                    ):
+
+                    is_plugin = False
+                    if "_abc_impl" in a_keys:
+                        for base in a_module.__bases__:
+                            if base.__name__ == "AutoGPTPluginTemplate":
+                                is_plugin = True
+                                break
+
+                    if is_plugin and a_module.__name__ != "AutoGPTPluginTemplate":
                         plugin_name = a_module.__name__
                         plugin_configured = plugins_config.get(plugin_name) is not None
                         plugin_enabled = plugins_config.is_enabled(plugin_name)


Code review comments:
diff_hunk: @@ -260,10 +260,15 @@ def scan_plugins(config: Config, debug: bool = False) -> List[AutoGPTPluginTempl
                         continue
                     a_module = getattr(zipped_module, key)
                     a_keys = dir(a_module)
-                    if (
-                        "_abc_impl" in a_keys
-                        and a_module.__name__ != "AutoGPTPluginTemplate"
-                    ):
+
+                    is_plugin = False
+                    if "_abc_impl" in a_keys:
+                        for base in a_module.__bases__:
+                            if base.__name__ == "AutoGPTPluginTemplate":
+                                is_plugin = True
+                                break
path: autogpt/plugins/__init__.py
text: @user1:
Have you considered just using `issubclass(a_module, AutoGPTPluginTemplate)`?