Convert to pip package
- Moved __init__.py and plugin.yaml into hermes_piper_plugin/ package directory - Added pyproject.toml with build config and entry point registration - Updated tests to reference new subdirectory paths - Updated README with pip-based installation instructions This converts the plugin from a flat layout (loaded via hermes plugins install) to a proper pip package with the 'hermes_agent.plugins' entry point.
This commit is contained in:
19
README.md
19
README.md
@@ -24,19 +24,24 @@ import is safe. The plugin also logs the effective default at session start.
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Ensure piper-tts is installed
|
# Install from the internal Hermes package registry
|
||||||
pip install piper-tts
|
pip install hermes-piper-plugin
|
||||||
|
|
||||||
# 2. Install the plugin from the internal Hermes repo
|
# Or install in editable mode for development
|
||||||
hermes plugins install ssh://git@code.lazyworkhorse.net:2222/Hermes/hermes-piper-plugin.git
|
git clone https://code.lazyworkhorse.net/gortium/hermes-piper-plugin.git
|
||||||
|
cd hermes-piper-plugin
|
||||||
# 3. Restart gateways to load the plugin
|
pip install -e .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note:** The plugin used to be installed via `hermes plugins install` from the
|
||||||
|
> old flat layout. It is now a proper pip package. The entry point
|
||||||
|
> `hermes_agent.plugins` is registered automatically when you install the
|
||||||
|
> package — Hermes discovers it on next startup.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/data/projects/hermes-piper-plugin
|
cd /path/to/hermes-piper-plugin
|
||||||
pip install pytest pyyaml
|
pip install pytest pyyaml
|
||||||
python -m pytest tests/ -v
|
python -m pytest tests/ -v
|
||||||
```
|
```
|
||||||
|
|||||||
18
pyproject.toml
Normal file
18
pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "hermes-piper-plugin"
|
||||||
|
version = "1.0.0"
|
||||||
|
description = "Piper TTS plugin for Hermes Agent"
|
||||||
|
authors = [{name = "@gortium"}]
|
||||||
|
license = {text = "MIT"}
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
[project.entry-points.'hermes_agent.plugins']
|
||||||
|
piper = "hermes_piper_plugin:register"
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
include = ["hermes_piper_plugin*", "tests*"]
|
||||||
@@ -62,7 +62,7 @@ def _clean_tools_tts():
|
|||||||
|
|
||||||
def _load_plugin_module(name: str) -> types.ModuleType:
|
def _load_plugin_module(name: str) -> types.ModuleType:
|
||||||
"""Load the plugin __init__.py as a fresh module with given name."""
|
"""Load the plugin __init__.py as a fresh module with given name."""
|
||||||
source = Path(__file__).resolve().parent.parent / "__init__.py"
|
source = Path(__file__).resolve().parent.parent / "hermes_piper_plugin" / "__init__.py"
|
||||||
assert source.exists(), f"Plugin init not found at {source}"
|
assert source.exists(), f"Plugin init not found at {source}"
|
||||||
spec = importlib.util.spec_from_file_location(name, str(source))
|
spec = importlib.util.spec_from_file_location(name, str(source))
|
||||||
mod = importlib.util.module_from_spec(spec)
|
mod = importlib.util.module_from_spec(spec)
|
||||||
@@ -85,7 +85,7 @@ def plugin_dir() -> Path:
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def manifest(plugin_dir: Path) -> dict:
|
def manifest(plugin_dir: Path) -> dict:
|
||||||
manifest_path = plugin_dir / "plugin.yaml"
|
manifest_path = plugin_dir / "hermes_piper_plugin" / "plugin.yaml"
|
||||||
assert manifest_path.exists(), f"plugin.yaml not found at {manifest_path}"
|
assert manifest_path.exists(), f"plugin.yaml not found at {manifest_path}"
|
||||||
with open(manifest_path) as f:
|
with open(manifest_path) as f:
|
||||||
return yaml.safe_load(f)
|
return yaml.safe_load(f)
|
||||||
@@ -274,14 +274,14 @@ class TestPluginStructure:
|
|||||||
|
|
||||||
def test_required_files_exist(self, plugin_dir):
|
def test_required_files_exist(self, plugin_dir):
|
||||||
"""Plugin must have plugin.yaml, __init__.py, and README.md."""
|
"""Plugin must have plugin.yaml, __init__.py, and README.md."""
|
||||||
assert (plugin_dir / "plugin.yaml").exists(), "Missing plugin.yaml"
|
assert (plugin_dir / "hermes_piper_plugin" / "plugin.yaml").exists(), "Missing plugin.yaml"
|
||||||
assert (plugin_dir / "__init__.py").exists(), "Missing __init__.py"
|
assert (plugin_dir / "hermes_piper_plugin" / "__init__.py").exists(), "Missing __init__.py"
|
||||||
assert (plugin_dir / "README.md").exists(), "Missing README.md"
|
assert (plugin_dir / "README.md").exists(), "Missing README.md"
|
||||||
|
|
||||||
def test_init_has_register_function(self, plugin_dir):
|
def test_init_has_register_function(self, plugin_dir):
|
||||||
"""__init__.py must expose a register() function."""
|
"""__init__.py must expose a register() function."""
|
||||||
spec = importlib.util.spec_from_file_location(
|
spec = importlib.util.spec_from_file_location(
|
||||||
"test_register_check", str(plugin_dir / "__init__.py")
|
"test_register_check", str(plugin_dir / "hermes_piper_plugin" / "__init__.py")
|
||||||
)
|
)
|
||||||
mod = importlib.util.module_from_spec(spec)
|
mod = importlib.util.module_from_spec(spec)
|
||||||
spec.loader.exec_module(mod)
|
spec.loader.exec_module(mod)
|
||||||
|
|||||||
Reference in New Issue
Block a user