From 45c8d3da960a56b22670ee2a695f9aa993921c53 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sun, 29 Mar 2026 16:53:29 -0700 Subject: [PATCH] fix(banner): show lazy-initialized tools in yellow instead of red (salvage #1854) (#3822) Tools from check_fn-gated toolsets (honcho, homeassistant) showed as red (disabled) in the startup banner even when properly configured. This happened because check_fn runs lazily after session context is set, but the banner renders before agent init. Now distinguishes three states: - red: truly unavailable (missing env var, no API key) - yellow: lazy-initialized (check_fn pending, will activate on use) - normal: available and ready Only the banner fix was salvaged from the original PR; unrelated bundled changes (context_compressor, STT config, auth default_model, SessionResetPolicy) were discarded. Co-authored-by: Jah-yee --- hermes_cli/banner.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hermes_cli/banner.py b/hermes_cli/banner.py index fafce906e..5ecc94acf 100644 --- a/hermes_cli/banner.py +++ b/hermes_cli/banner.py @@ -258,7 +258,7 @@ def build_welcome_banner(console: Console, model: str, cwd: str, get_toolset_for_tool: Callable to map tool name -> toolset name. context_length: Model's context window size in tokens. """ - from model_tools import check_tool_availability + from model_tools import check_tool_availability, TOOLSET_REQUIREMENTS if get_toolset_for_tool is None: from model_tools import get_toolset_for_tool @@ -267,8 +267,18 @@ def build_welcome_banner(console: Console, model: str, cwd: str, _, unavailable_toolsets = check_tool_availability(quiet=True) disabled_tools = set() + # Tools whose toolset has a check_fn are lazy-initialized (e.g. honcho, + # homeassistant) — they show as unavailable at banner time because the + # check hasn't run yet, but they aren't misconfigured. + lazy_tools = set() for item in unavailable_toolsets: - disabled_tools.update(item.get("tools", [])) + toolset_name = item.get("name", "") + ts_req = TOOLSET_REQUIREMENTS.get(toolset_name, {}) + tools_in_ts = item.get("tools", []) + if ts_req.get("check_fn"): + lazy_tools.update(tools_in_ts) + else: + disabled_tools.update(tools_in_ts) layout_table = Table.grid(padding=(0, 2)) layout_table.add_column("left", justify="center") @@ -328,6 +338,8 @@ def build_welcome_banner(console: Console, model: str, cwd: str, for name in sorted(tool_names): if name in disabled_tools: colored_names.append(f"[red]{name}[/]") + elif name in lazy_tools: + colored_names.append(f"[yellow]{name}[/]") else: colored_names.append(f"[{text}]{name}[/]") @@ -347,6 +359,8 @@ def build_welcome_banner(console: Console, model: str, cwd: str, colored_names.append("[dim]...[/]") elif name in disabled_tools: colored_names.append(f"[red]{name}[/]") + elif name in lazy_tools: + colored_names.append(f"[yellow]{name}[/]") else: colored_names.append(f"[{text}]{name}[/]") tools_str = ", ".join(colored_names)