Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion agent/title_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,38 @@ def _title_language() -> str:
return ""


# Mirror of utils.TRUTHY_STRINGS for the opposite side. `is_truthy_value`
# answers "is this truthy?", which collapses "explicitly off" and "not a value
# I recognise" into the same False — fine for an env var, wrong for a config
# knob whose default is on (see _auto_title_enabled).
_FALSY_STRINGS = frozenset({"0", "false", "no", "off"})


def _auto_title_enabled() -> bool:
"""Return whether automatic session title generation is enabled.

Only a value that actually says "off" disables titling. An unrecognised
value keeps the documented default (on) and warns: ``enabled: ture`` is
YAML for the string "ture", so a user typo made while trying to *enable*
titling would otherwise turn it off silently, for as long as it goes
unnoticed.
"""
try:
from utils import is_truthy_value
return is_truthy_value(_title_config().get("enabled"), default=True)

raw = _title_config().get("enabled")
if isinstance(raw, str):
token = raw.strip().lower()
from utils import TRUTHY_STRINGS

if token not in TRUTHY_STRINGS and token not in _FALSY_STRINGS:
logger.warning(
"Ignoring unrecognised auxiliary.title_generation.enabled=%r; "
"auto-title stays on. Use true or false.",
raw,
)
return True
return is_truthy_value(raw, default=True)
except Exception:
logger.debug("Failed to read title_generation.enabled", exc_info=True)
return True
Expand Down
42 changes: 42 additions & 0 deletions tests/agent/test_title_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
maybe_auto_title,
wait_for_title_upgrades,
_title_language,
_auto_title_enabled,
)
from hermes_state import SessionDB

Expand Down Expand Up @@ -78,6 +79,47 @@ def test_title_language_reads_config(self):
patch("hermes_cli.config.load_config_readonly", side_effect=RuntimeError("bad config")):
assert _title_language() == ""

@pytest.mark.parametrize("raw", [True, "true", "yes", "on", "1", " True "])
def test_recognised_truthy_values_enable_titling(self, raw):
from agent import title_generator as tg

with patch.object(tg, "_title_config", return_value={"enabled": raw}):
assert _auto_title_enabled() is True

@pytest.mark.parametrize("raw", [False, "false", "no", "off", "0"])
def test_recognised_falsy_values_disable_titling(self, raw):
from agent import title_generator as tg

with patch.object(tg, "_title_config", return_value={"enabled": raw}):
assert _auto_title_enabled() is False

@pytest.mark.parametrize("raw", ["ture", "treu", "enabled", "maybe", ""])
def test_unrecognised_value_keeps_titling_on_and_warns(self, raw, caplog):
"""A value the truthy set doesn't recognise is a typo, not consent.

``enabled: ture`` is YAML for the string "ture", which is not in
``TRUTHY_STRINGS`` — so a user typing it while trying to *enable*
titling silently loses it. Only ``enabled`` values that actually say
"off" turn titling off; anything else keeps the documented default and
says so in the log.
"""
from agent import title_generator as tg

with patch.object(tg, "_title_config", return_value={"enabled": raw}):
assert _auto_title_enabled() is True

assert any(
"title_generation.enabled" in r.message and raw in r.message
for r in caplog.records
)

def test_absent_key_keeps_documented_default(self):
from agent import title_generator as tg

for cfg in ({}, {"enabled": None}):
with patch.object(tg, "_title_config", return_value=cfg):
assert _auto_title_enabled() is True


def test_generate_title_disables_reasoning(self):
"""The titling pass must explicitly disable thinking (#91927).
Expand Down