Compare commits
2 Commits
v2026.8.13
...
v2026.5.29
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77a1650c78 | ||
|
|
827f7f0782 |
@@ -1,4 +1,9 @@
|
||||
graft skills
|
||||
graft optional-skills
|
||||
# Bundled plugin manifests (plugin.yaml / plugin.yml). Without these the
|
||||
# PluginManager scan (hermes_cli/plugins.py) finds zero plugins on installs
|
||||
# built from the sdist (e.g. Homebrew, downstream packagers). package-data
|
||||
# below covers the wheel; this covers the sdist. See #34034 / #28149.
|
||||
recursive-include plugins plugin.yaml plugin.yml
|
||||
global-exclude __pycache__
|
||||
global-exclude *.py[cod]
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
{
|
||||
"id": "hermes-agent",
|
||||
"name": "Hermes Agent",
|
||||
"version": "0.15.1",
|
||||
"version": "0.15.2",
|
||||
"description": "Self-improving open-source AI agent by Nous Research with ACP editor integration, persistent memory, skills, and rich tool support.",
|
||||
"repository": "https://github.com/NousResearch/hermes-agent",
|
||||
"website": "https://hermes-agent.nousresearch.com/docs/user-guide/features/acp",
|
||||
"authors": ["Nous Research"],
|
||||
"authors": [
|
||||
"Nous Research"
|
||||
],
|
||||
"license": "MIT",
|
||||
"distribution": {
|
||||
"uvx": {
|
||||
"package": "hermes-agent[acp]==0.15.1",
|
||||
"args": ["hermes-acp"]
|
||||
"package": "hermes-agent[acp]==0.15.2",
|
||||
"args": [
|
||||
"hermes-acp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ Provides subcommands for:
|
||||
import os
|
||||
import sys
|
||||
|
||||
__version__ = "0.15.1"
|
||||
__release_date__ = "2026.5.29"
|
||||
__version__ = "0.15.2"
|
||||
__release_date__ = "2026.5.29.2"
|
||||
|
||||
|
||||
def _ensure_utf8():
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "hermes-agent"
|
||||
version = "0.15.1"
|
||||
version = "0.15.2"
|
||||
description = "The self-improving AI agent — creates skills from experience, improves them during use, and runs anywhere"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
@@ -226,6 +226,14 @@ plugins = [
|
||||
"*/dashboard/manifest.json",
|
||||
"*/dashboard/dist/*",
|
||||
"*/dashboard/dist/**/*",
|
||||
# Plugin discovery (hermes_cli/plugins.py) reads a plugin.yaml/plugin.yml
|
||||
# manifest from each bundled plugin directory to register it. Wheels only
|
||||
# carry files declared here, so without this glob the wheel ships every
|
||||
# plugin's Python code but none of its manifests — the scan finds zero
|
||||
# plugins and all gateway platforms fail with "No adapter available for
|
||||
# <platform>" (#34034), web-search providers go missing (#28149), etc.
|
||||
"**/plugin.yaml",
|
||||
"**/plugin.yml",
|
||||
]
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
|
||||
@@ -20,3 +20,42 @@ def test_manifest_includes_bundled_skills():
|
||||
|
||||
assert "graft skills" in manifest
|
||||
assert "graft optional-skills" in manifest
|
||||
|
||||
|
||||
def test_bundled_plugin_manifests_ship_in_both_wheel_and_sdist():
|
||||
"""Regression test for #34034 / #28149.
|
||||
|
||||
Plugin discovery (hermes_cli/plugins.py) registers each bundled plugin by
|
||||
reading its ``plugin.yaml`` / ``plugin.yml`` manifest. Those manifests are
|
||||
data files, not Python modules, so they only reach installed packages when
|
||||
declared explicitly:
|
||||
|
||||
- wheel -> ``[tool.setuptools.package-data]`` ``plugins`` glob
|
||||
- sdist -> ``MANIFEST.in`` (Homebrew and other downstream packagers build
|
||||
from the sdist)
|
||||
|
||||
v0.15.0 declared neither, so the wheel shipped every adapter's Python code
|
||||
but none of its manifests, and *every* gateway platform failed with
|
||||
"No adapter available for <platform>". Both channels must cover manifests.
|
||||
"""
|
||||
# There must actually be manifests on disk for the globs to match.
|
||||
on_disk = list((REPO_ROOT / "plugins").rglob("plugin.yaml")) + list(
|
||||
(REPO_ROOT / "plugins").rglob("plugin.yml")
|
||||
)
|
||||
assert on_disk, "expected bundled plugin manifests under plugins/"
|
||||
|
||||
# Wheel channel: package-data must declare a glob that matches plugin
|
||||
# manifests anywhere under the plugins package.
|
||||
data = tomllib.loads((REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
||||
plugins_pkg_data = data["tool"]["setuptools"]["package-data"].get("plugins", [])
|
||||
assert any(
|
||||
g.endswith("plugin.yaml") or g.endswith("plugin.yml")
|
||||
for g in plugins_pkg_data
|
||||
), "pyproject package-data 'plugins' must ship plugin.yaml/plugin.yml (wheel)"
|
||||
|
||||
# Sdist channel: MANIFEST.in must recursively include the manifests so
|
||||
# downstream packagers building from the sdist also get them.
|
||||
manifest = (REPO_ROOT / "MANIFEST.in").read_text(encoding="utf-8")
|
||||
assert "recursive-include plugins" in manifest and "plugin.yaml" in manifest, (
|
||||
"MANIFEST.in must recursive-include plugins plugin.yaml/plugin.yml (sdist)"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user