mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix: add _profile_arg tests + move STT language to config.yaml
- Add 7 unit tests for _profile_arg: default home, named profile, hash path, nested path, invalid name, systemd integration, launchd integration - Add stt.local.language to config.yaml (empty = auto-detect) - Both STT code paths now read config.yaml first, env var fallback, then default (auto-detect for faster-whisper, 'en' for CLI command) - HERMES_LOCAL_STT_LANGUAGE env var still works as backward-compat fallback
This commit is contained in:
parent
6e02fa73c2
commit
f3c59321af
3 changed files with 79 additions and 3 deletions
|
|
@ -416,6 +416,7 @@ DEFAULT_CONFIG = {
|
||||||
"provider": "local", # "local" (free, faster-whisper) | "groq" | "openai" (Whisper API)
|
"provider": "local", # "local" (free, faster-whisper) | "groq" | "openai" (Whisper API)
|
||||||
"local": {
|
"local": {
|
||||||
"model": "base", # tiny, base, small, medium, large-v3
|
"model": "base", # tiny, base, small, medium, large-v3
|
||||||
|
"language": "", # auto-detect by default; set to "en", "es", "fr", etc. to force
|
||||||
},
|
},
|
||||||
"openai": {
|
"openai": {
|
||||||
"model": "whisper-1", # whisper-1, gpt-4o-mini-transcribe, gpt-4o-transcribe
|
"model": "whisper-1", # whisper-1, gpt-4o-mini-transcribe, gpt-4o-transcribe
|
||||||
|
|
|
||||||
|
|
@ -641,3 +641,69 @@ class TestEnsureUserSystemdEnv:
|
||||||
result = gateway_cli._systemctl_cmd(system=True)
|
result = gateway_cli._systemctl_cmd(system=True)
|
||||||
assert result == ["systemctl"]
|
assert result == ["systemctl"]
|
||||||
assert calls == []
|
assert calls == []
|
||||||
|
|
||||||
|
|
||||||
|
class TestProfileArg:
|
||||||
|
"""Tests for _profile_arg — returns '--profile <name>' for named profiles."""
|
||||||
|
|
||||||
|
def test_default_hermes_home_returns_empty(self, tmp_path, monkeypatch):
|
||||||
|
"""Default ~/.hermes should not produce a --profile flag."""
|
||||||
|
hermes_home = tmp_path / ".hermes"
|
||||||
|
hermes_home.mkdir()
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
result = gateway_cli._profile_arg(str(hermes_home))
|
||||||
|
assert result == ""
|
||||||
|
|
||||||
|
def test_named_profile_returns_flag(self, tmp_path, monkeypatch):
|
||||||
|
"""~/.hermes/profiles/mybot should return '--profile mybot'."""
|
||||||
|
profile_dir = tmp_path / ".hermes" / "profiles" / "mybot"
|
||||||
|
profile_dir.mkdir(parents=True)
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
result = gateway_cli._profile_arg(str(profile_dir))
|
||||||
|
assert result == "--profile mybot"
|
||||||
|
|
||||||
|
def test_hash_path_returns_empty(self, tmp_path, monkeypatch):
|
||||||
|
"""Arbitrary non-profile HERMES_HOME should return empty string."""
|
||||||
|
custom_home = tmp_path / "custom" / "hermes"
|
||||||
|
custom_home.mkdir(parents=True)
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
result = gateway_cli._profile_arg(str(custom_home))
|
||||||
|
assert result == ""
|
||||||
|
|
||||||
|
def test_nested_profile_path_returns_empty(self, tmp_path, monkeypatch):
|
||||||
|
"""~/.hermes/profiles/mybot/subdir should NOT match — too deep."""
|
||||||
|
nested = tmp_path / ".hermes" / "profiles" / "mybot" / "subdir"
|
||||||
|
nested.mkdir(parents=True)
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
result = gateway_cli._profile_arg(str(nested))
|
||||||
|
assert result == ""
|
||||||
|
|
||||||
|
def test_invalid_profile_name_returns_empty(self, tmp_path, monkeypatch):
|
||||||
|
"""Profile names with invalid chars should not match the regex."""
|
||||||
|
bad_profile = tmp_path / ".hermes" / "profiles" / "My Bot!"
|
||||||
|
bad_profile.mkdir(parents=True)
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
result = gateway_cli._profile_arg(str(bad_profile))
|
||||||
|
assert result == ""
|
||||||
|
|
||||||
|
def test_systemd_unit_includes_profile(self, tmp_path, monkeypatch):
|
||||||
|
"""generate_systemd_unit should include --profile in ExecStart for named profiles."""
|
||||||
|
profile_dir = tmp_path / ".hermes" / "profiles" / "mybot"
|
||||||
|
profile_dir.mkdir(parents=True)
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
monkeypatch.setenv("HERMES_HOME", str(profile_dir))
|
||||||
|
monkeypatch.setattr(gateway_cli, "get_hermes_home", lambda: profile_dir)
|
||||||
|
unit = gateway_cli.generate_systemd_unit(system=False)
|
||||||
|
assert "--profile mybot" in unit
|
||||||
|
assert "gateway run --replace" in unit
|
||||||
|
|
||||||
|
def test_launchd_plist_includes_profile(self, tmp_path, monkeypatch):
|
||||||
|
"""generate_launchd_plist should include --profile in ProgramArguments for named profiles."""
|
||||||
|
profile_dir = tmp_path / ".hermes" / "profiles" / "mybot"
|
||||||
|
profile_dir.mkdir(parents=True)
|
||||||
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
||||||
|
monkeypatch.setenv("HERMES_HOME", str(profile_dir))
|
||||||
|
monkeypatch.setattr(gateway_cli, "get_hermes_home", lambda: profile_dir)
|
||||||
|
plist = gateway_cli.generate_launchd_plist()
|
||||||
|
assert "<string>--profile</string>" in plist
|
||||||
|
assert "<string>mybot</string>" in plist
|
||||||
|
|
|
||||||
|
|
@ -295,8 +295,12 @@ def _transcribe_local(file_path: str, model_name: str) -> Dict[str, Any]:
|
||||||
_local_model = WhisperModel(model_name, device="auto", compute_type="auto")
|
_local_model = WhisperModel(model_name, device="auto", compute_type="auto")
|
||||||
_local_model_name = model_name
|
_local_model_name = model_name
|
||||||
|
|
||||||
# Allow forcing the language via env var (e.g. HERMES_LOCAL_STT_LANGUAGE=en)
|
# Language: config.yaml (stt.local.language) > env var > auto-detect.
|
||||||
_forced_lang = os.getenv(LOCAL_STT_LANGUAGE_ENV, DEFAULT_LOCAL_STT_LANGUAGE)
|
_forced_lang = (
|
||||||
|
_load_stt_config().get("local", {}).get("language")
|
||||||
|
or os.getenv(LOCAL_STT_LANGUAGE_ENV)
|
||||||
|
or None
|
||||||
|
)
|
||||||
transcribe_kwargs = {"beam_size": 5}
|
transcribe_kwargs = {"beam_size": 5}
|
||||||
if _forced_lang:
|
if _forced_lang:
|
||||||
transcribe_kwargs["language"] = _forced_lang
|
transcribe_kwargs["language"] = _forced_lang
|
||||||
|
|
@ -350,7 +354,12 @@ def _transcribe_local_command(file_path: str, model_name: str) -> Dict[str, Any]
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
language = os.getenv(LOCAL_STT_LANGUAGE_ENV, DEFAULT_LOCAL_STT_LANGUAGE)
|
# Language: config.yaml (stt.local.language) > env var > "en" default.
|
||||||
|
language = (
|
||||||
|
_load_stt_config().get("local", {}).get("language")
|
||||||
|
or os.getenv(LOCAL_STT_LANGUAGE_ENV)
|
||||||
|
or DEFAULT_LOCAL_STT_LANGUAGE
|
||||||
|
)
|
||||||
normalized_model = _normalize_local_command_model(model_name)
|
normalized_model = _normalize_local_command_model(model_name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue