Toggle to enable/disable automatic title generation
Cluster 27877 · agent. Data as of
1 open item. Fix merged in #113955 on 17 Sep 2026. Check it covers your case.
The short answer
- Known?
- Yes. 10 related items grouped here, 3 issues already closed.
- Fix event
- A fix was merged to main in PR #113955. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
unresolved. That is separate from the fix event. - Still open
- 1 issue and 0 PRs.
Next step: read #113955, then check whether your report is the one still open.
Read #113955Pick up a Lab taskThese issues and pull requests concern adding and correctly honoring a configuration setting to enable or disable auxiliary title generation. Multiple bug reports indicate the enabled flag is ignored, with several fix attempts addressing this behavior.
Open issues1
- Issue#29456[Feature]: Ability to toggle title generation
Open PRs0
Fixes on record
-
#66049 fix(title): honor auxiliary.title_generation.enabled to disable auto titles (salvage #37349)
files:
agent/title_generator.py,cli-config.yaml.example,hermes_cli/config.py,scripts/release.py,tests/agent/test_title_generator.py,tests/hermes_cli/test_aux_config.py,website/docs/user-guide/configuration.mdShow the diff
-
agent/title_generator.py@@ -48,6 +48,23 @@ def _title_language() -> str: return "" +def _auto_title_enabled() -> bool: + """Return whether automatic session title generation is enabled.""" + try: + # Lazy imports, matching _title_language(): title_generator is imported + # from agent code paths where a module-level hermes_cli import risks + # circularity, and the read-only loader avoids config-migration writes. + from hermes_cli.config import load_config_readonly + from utils import is_truthy_value + + config = load_config_readonly() + title_config = (config.get("auxiliary") or {}).get("title_generation") or {} + return is_truthy_value(title_config.get("enabled"), default=True) + except Exception: + logger.debug("Failed to read title_generation.enabled", exc_info=True) + return True + + def generate_title( user_message: str, assistant_response: str, @@ -66,6 +83,10 @@ def generate_title( ``AIAgent._emit_auxiliary_failure`` so the user sees a warning instead of silently accumulating untitled sessions. """ + if not _auto_title_enabled(): + logger.debug("Auto-title skipped: auxiliary.title_generation.enabled=false") + return None + # Truncate long messages to keep the request small user_snippet = user_message[:500] if user_message else "" assistant_snippet = assistant_response[:500] if assistant_response else "" @@ -254,6 +275,12 @@ def maybe_auto_title( if user_msg_count > 2: return + # Config read comes after the cheap first-exchange guard so the file + # isn't touched on every subsequent turn of a long session. + if not _auto_title_enabled(): + logger.debug("Auto-title skipped: auxiliary.title_generation.enabled=false") + return + thread = threading.Thread( target=auto_title_session, args=(session_db, session_id, user_message, assistant_response), -
cli-config.yaml.example@@ -526,6 +526,14 @@ prompt_caching: # model: "" # timeout: 30 # +# # Automatic session title generation after the first exchange +# title_generation: +# enabled: true # set false to disable auto-title generation +# provider: "auto" +# model: "" +# timeout: 30 +# language: "" # empty = match the user's language; or e.g. "English" +# # # Session search — summarizes matching past sessions # session_search: # provider: "auto" -
hermes_cli/config.py@@ -1643,6 +1643,7 @@ def _ensure_hermes_home_managed(home: Path): "reasoning_effort": "", # per-task thinking level: none|minimal|low|medium|high|xhigh|max|ultra (empty = provider default) }, "title_generation": { + "enabled": True, "provider": "auto", "model": "", "base_url": "", -
scripts/release.py@@ -363,6 +363,7 @@ "[email protected]": "synapsesx", "[email protected]": "itsflownium", "[email protected]": "dirtyren", + "[redacted:email]": "s96919", "[redacted:email]": "doxe0x", "[redacted:email]": "Code-suphub", "[email protected]": "Code-suphub", -
tests/agent/test_title_generator.py@@ -210,6 +210,18 @@ def mock_call_llm(**kwargs): user_content = captured_kwargs["messages"][1]["content"] assert len(user_content) < 1100 # 500 + 500 + formatting + def test_skips_when_title_generation_disabled(self): + """auxiliary.title_generation.enabled=false disables automatic titles.""" + config = {"auxiliary": {"title_generation": {"enabled": False}}} + + with ( + patch("hermes_cli.config.load_config_readonly", return_value=config), + patch("agent.title_generator.call_llm") as mock_call_llm, + ): + assert generate_title("question", "answer") is None + + mock_call_llm.assert_not_called() + class TestAutoTitleSession: """Tests for auto_title_session() — the sync worker function.""" @@ -347,6 +359,23 @@ def test_fires_on_first_exchange(self): title_callback=None, ) + def test_skips_when_title_generation_disabled(self): + """Disabled title generation should not even start the background worker.""" + db = MagicMock() + history = [ + {"role": "user", "content": "hello"}, + {"role": "assistant", "content": "hi there"}, + ] + config = {"auxiliary": {"title_generation": {"enabled": False}}} + + with ( + patch("hermes_cli.config.load_config_readonly", return_value=config), + patch("agent.title_generator.auto_title_session") as mock_auto, + ): + maybe_auto_title(db, "sess-1", "hello", "hi there", history) + + mock_auto.assert_not_called() + def test_forwards_failure_callback_to_worker(self): """maybe_auto_title must forward failure_callback into the thread.""" db = MagicMock() -
tests/hermes_cli/test_aux_config.py@@ -36,6 +36,7 @@ def test_title_generation_present_in_default_config(): """ assert "title_generation" in DEFAULT_CONFIG["auxiliary"] tg = DEFAULT_CONFIG["auxiliary"]["title_generation"] + assert tg["enabled"] is True assert tg["provider"] == "auto" assert tg["model"] == "" assert tg["timeout"] > 0 -
website/docs/user-guide/configuration.md@@ -958,6 +958,10 @@ $ hermes model Select a task, pick a provider (OAuth flows open a browser; API-key providers prompt), pick a model. The change persists to `auxiliary.<task>.*` in `config.yaml`. Same machinery as the main-model picker — no extra syntax to learn. +If you do not want Hermes to auto-generate titles after the first exchange, set +`auxiliary.title_generation.enabled: false`. Manual titles still work through +`/title` and `hermes sessions rename`. + ### Video Tutorial <div style={{position: 'relative', width: '100%', aspectRatio: '16 / 9', marginBottom: '1.5rem'}}> @@ -1070,6 +1074,7 @@ auxiliary: # Auto-generated session titles. Empty language follows the conversation; # set e.g. "English" or "Japanese" to pin titles to one language. title_generation: + enabled: true # set false to disable auto-title generation provider: "auto" model: "" base_url: ""
-
-
#113955 fix(aux): session titles keep the instant derived title while the model upgrade is switched off (#85194, salvage #85401)
files:
agent/title_generator.py,cli-config.yaml.example,contributors/emails/[redacted:email],hermes_cli/config_defaults.py,tests/agent/test_title_generator.py,website/docs/user-guide/configuration.md
4 PRs closed without merging
From the close comments: done elsewhere 3 · duplicate 1
-
#27977 feat(auxiliary): add enabled toggle for individual auxiliary tasks (#27877) · done elsewhere →
e20c3c1,#113955 -
#41760 fix(auxiliary): respect auxiliary.title_generation.enabled config · done elsewhere →
#66049,#37349 -
#41951 fix(title_gen): honor auxiliary.title_generation.enabled config setting (#41744) · duplicate →
#41760,#41744,#37349 -
#42098 fix(agent): honor auxiliary.title_generation.enabled to disable auto titles · done elsewhere →
#66049,#37349
Closed issues · 3
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.16: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the Lab