mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
Fix variable name breakage (run_agent, hermes_constants, etc.) where import rewriter changed 'import X' to 'import hermes_agent.Y' but test code still referenced 'X' as a variable name. Fix package-vs-module confusion (cli.auth, cli.models, cli.ui) where single files became directories. Fix hardcoded file paths in tests pointing to old locations. Fix tool registry to discover tools in subpackage directories. Fix stale import in hermes_agent/tools/__init__.py. Part of #14182, #14183
174 lines
6.3 KiB
Python
174 lines
6.3 KiB
Python
"""Tests for plugin image_gen providers injecting themselves into the picker.
|
|
|
|
Covers `_plugin_image_gen_providers`, `_visible_providers`, and
|
|
`_toolset_needs_configuration_prompt` handling of plugin providers.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from hermes_agent.agent.image_gen import registry as image_gen_registry
|
|
from hermes_agent.agent.image_gen.provider import ImageGenProvider
|
|
|
|
|
|
class _FakeProvider(ImageGenProvider):
|
|
def __init__(self, name: str, available: bool = True, schema=None, models=None):
|
|
self._name = name
|
|
self._available = available
|
|
self._schema = schema or {
|
|
"name": name.title(),
|
|
"badge": "test",
|
|
"tag": f"{name} test tag",
|
|
"env_vars": [{"key": f"{name.upper()}_API_KEY", "prompt": f"{name} key"}],
|
|
}
|
|
self._models = models or [
|
|
{"id": f"{name}-model-v1", "display": f"{name} v1",
|
|
"speed": "~5s", "strengths": "test", "price": "$"},
|
|
]
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return self._name
|
|
|
|
def is_available(self) -> bool:
|
|
return self._available
|
|
|
|
def list_models(self):
|
|
return list(self._models)
|
|
|
|
def default_model(self):
|
|
return self._models[0]["id"] if self._models else None
|
|
|
|
def get_setup_schema(self):
|
|
return dict(self._schema)
|
|
|
|
def generate(self, prompt, aspect_ratio="landscape", **kw):
|
|
return {"success": True, "image": f"{self._name}://{prompt}"}
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _reset_registry():
|
|
image_gen_registry._reset_for_tests()
|
|
yield
|
|
image_gen_registry._reset_for_tests()
|
|
|
|
|
|
class TestPluginPickerInjection:
|
|
def test_plugin_providers_returns_registered(self, monkeypatch):
|
|
from hermes_agent.cli import tools_config
|
|
|
|
image_gen_registry.register_provider(_FakeProvider("myimg"))
|
|
|
|
rows = tools_config._plugin_image_gen_providers()
|
|
names = [r["name"] for r in rows]
|
|
plugin_names = [r.get("image_gen_plugin_name") for r in rows]
|
|
|
|
assert "Myimg" in names
|
|
assert "myimg" in plugin_names
|
|
|
|
def test_fal_skipped_to_avoid_duplicate(self, monkeypatch):
|
|
from hermes_agent.cli import tools_config
|
|
|
|
# Simulate a FAL plugin being registered — the picker already has
|
|
# hardcoded FAL rows in TOOL_CATEGORIES, so plugin-FAL must be
|
|
# skipped to avoid showing FAL twice.
|
|
image_gen_registry.register_provider(_FakeProvider("fal"))
|
|
image_gen_registry.register_provider(_FakeProvider("openai"))
|
|
|
|
rows = tools_config._plugin_image_gen_providers()
|
|
names = [r.get("image_gen_plugin_name") for r in rows]
|
|
assert "fal" not in names
|
|
assert "openai" in names
|
|
|
|
def test_visible_providers_includes_plugins_for_image_gen(self, monkeypatch):
|
|
from hermes_agent.cli import tools_config
|
|
|
|
image_gen_registry.register_provider(_FakeProvider("someimg"))
|
|
|
|
cat = tools_config.TOOL_CATEGORIES["image_gen"]
|
|
visible = tools_config._visible_providers(cat, {})
|
|
plugin_names = [p.get("image_gen_plugin_name") for p in visible if p.get("image_gen_plugin_name")]
|
|
assert "someimg" in plugin_names
|
|
|
|
def test_visible_providers_does_not_inject_into_other_categories(self, monkeypatch):
|
|
from hermes_agent.cli import tools_config
|
|
|
|
image_gen_registry.register_provider(_FakeProvider("someimg"))
|
|
|
|
# Browser category must NOT see image_gen plugins.
|
|
browser = tools_config.TOOL_CATEGORIES["browser"]
|
|
visible = tools_config._visible_providers(browser, {})
|
|
assert all(p.get("image_gen_plugin_name") is None for p in visible)
|
|
|
|
|
|
class TestPluginCatalog:
|
|
def test_plugin_catalog_returns_models(self):
|
|
from hermes_agent.cli import tools_config
|
|
|
|
image_gen_registry.register_provider(_FakeProvider("catimg"))
|
|
|
|
catalog, default = tools_config._plugin_image_gen_catalog("catimg")
|
|
assert "catimg-model-v1" in catalog
|
|
assert default == "catimg-model-v1"
|
|
|
|
def test_plugin_catalog_empty_for_unknown(self):
|
|
from hermes_agent.cli import tools_config
|
|
|
|
catalog, default = tools_config._plugin_image_gen_catalog("does-not-exist")
|
|
assert catalog == {}
|
|
assert default is None
|
|
|
|
|
|
class TestConfigPrompt:
|
|
def test_image_gen_satisfied_by_plugin_provider(self, monkeypatch, tmp_path):
|
|
"""When a plugin provider reports is_available(), the picker should
|
|
not force a setup prompt on the user."""
|
|
from hermes_agent.cli import tools_config
|
|
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.delenv("FAL_KEY", raising=False)
|
|
|
|
image_gen_registry.register_provider(_FakeProvider("avail-img", available=True))
|
|
|
|
assert tools_config._toolset_needs_configuration_prompt("image_gen", {}) is False
|
|
|
|
def test_image_gen_still_prompts_when_nothing_available(self, monkeypatch, tmp_path):
|
|
from hermes_agent.cli import tools_config
|
|
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
monkeypatch.delenv("FAL_KEY", raising=False)
|
|
|
|
image_gen_registry.register_provider(_FakeProvider("unavail-img", available=False))
|
|
|
|
assert tools_config._toolset_needs_configuration_prompt("image_gen", {}) is True
|
|
|
|
|
|
class TestConfigWriting:
|
|
def test_picking_plugin_provider_writes_provider_and_model(self, monkeypatch, tmp_path):
|
|
"""When a user picks a plugin-backed image_gen provider with no
|
|
env vars needed, ``_configure_provider`` should write both
|
|
``image_gen.provider`` and ``image_gen.model``."""
|
|
from hermes_agent.cli import tools_config
|
|
|
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
|
image_gen_registry.register_provider(_FakeProvider("noenv", schema={
|
|
"name": "NoEnv",
|
|
"badge": "free",
|
|
"tag": "",
|
|
"env_vars": [],
|
|
}))
|
|
|
|
# Stub out the interactive model picker — no TTY in tests.
|
|
monkeypatch.setattr(tools_config, "_prompt_choice", lambda *a, **kw: 0)
|
|
|
|
config: dict = {}
|
|
provider_row = {
|
|
"name": "NoEnv",
|
|
"env_vars": [],
|
|
"image_gen_plugin_name": "noenv",
|
|
}
|
|
tools_config._configure_provider(provider_row, config)
|
|
|
|
assert config["image_gen"]["provider"] == "noenv"
|
|
assert config["image_gen"]["model"] == "noenv-model-v1"
|