fix(tui): guard personality overlay when personalities is null

TUI auto-resolves `display.personality` at session init, unlike the base CLI.
If config contains `agent.personalities: null`, `_resolve_personality_prompt`
called `.get()` on None and failed before model/provider selection.
Normalize null personalities to `{}` and surface a targeted config warning.
This commit is contained in:
Brooklyn Nicholson 2026-04-24 12:57:51 -05:00
parent bfa60234c8
commit e3940f9807
2 changed files with 77 additions and 12 deletions

View file

@ -67,11 +67,25 @@ def test_probe_config_health_flags_null_sections():
assert "model" not in msg
def test_probe_config_health_flags_null_personalities_with_active_personality():
from tui_gateway.server import _probe_config_health
msg = _probe_config_health(
{
"agent": {"personalities": None},
"display": {"personality": "kawaii"},
"model": {},
}
)
assert "display.personality" in msg
assert "agent.personalities" in msg
def test_make_agent_tolerates_null_config_sections():
"""Bare `agent:` / `display:` keys in ~/.hermes/config.yaml parse as
None. cfg.get("agent", {}) returns None (default only fires on missing
key), so downstream .get() chains must be guarded. Reported via Twitter
against the new TUI; CLI path is unaffected."""
against the new TUI."""
fake_runtime = {
"provider": "openrouter",
@ -99,3 +113,37 @@ def test_make_agent_tolerates_null_config_sections():
_make_agent("sid-null", "key-null")
assert mock_agent.called
def test_make_agent_tolerates_null_personalities_with_active_personality():
fake_runtime = {
"provider": "openrouter",
"base_url": "https://api.synthetic.new/v1",
"api_key": "sk-test",
"api_mode": "chat_completions",
"command": None,
"args": None,
"credential_pool": None,
}
cfg = {
"agent": {"personalities": None},
"display": {"personality": "kawaii"},
"model": {"default": "glm-5"},
}
with (
patch("tui_gateway.server._load_cfg", return_value=cfg),
patch("tui_gateway.server._get_db", return_value=MagicMock()),
patch("cli.load_cli_config", return_value={"agent": {"personalities": None}}),
patch(
"hermes_cli.runtime_provider.resolve_runtime_provider",
return_value=fake_runtime,
),
patch("run_agent.AIAgent") as mock_agent,
):
from tui_gateway.server import _make_agent
_make_agent("sid-null-personality", "key-null-personality")
assert mock_agent.called
assert mock_agent.call_args.kwargs["ephemeral_system_prompt"] is None