From b67ea7ff474831743b14edefb6c9113cb12216e7 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sat, 9 May 2026 18:20:28 -0700 Subject: [PATCH] perf(cli): skip welcome banner on `chat -q` single-query mode (#22904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `hermes chat -q "..."` printed the full welcome banner before running the query — kawaii ASCII logo, available toolsets list, available skills list, model name, session ID, working directory, update-available notice. Building it took ~420 ms on cold start (~200 ms version-update probe, the rest is toolset / skill enumeration plus Rich panel rendering). For a one-shot `-q` query the banner is noise: the user already picked the prompt, doesn't need a toolset reference, and gets the session ID + resume hint from `_print_exit_summary()` after the response prints. The fully-quiet `-Q` / `--quiet` machine-readable path was already banner-free; this brings the human-facing single-query path in line so all non-interactive invocations are fast. Measured impact (`hermes chat -q "ok" --max-turns 1`, 10-run percentiles, 9950X3D): median: 1.90 → 1.75 s (-150 ms) min: 1.80 → 1.73 s ( -70 ms) P25: 1.82 → 1.74 s ( -80 ms) Wider variance than expected; the banner cost overlaps with API latency on real `chat -q` runs. Min-time delta of 70 ms is the cleanest signal — that's the deterministic banner-build cost gone. The 150 ms median delta picks up cases where the version-update probe also finishes during the wait. Interactive mode (`hermes` with no `-q`) and the `--list-tools` / `--list-toolsets` one-shot listing commands still show the banner — those are the contexts where it's actually wanted. Tests: 656/656 `tests/cli/` pass on top of latest main (modulo 5 pre- existing flakes in `test_cli_save_config_value.py` that fail with `No module named 'ruamel'` both with and without this change). --- cli.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cli.py b/cli.py index 6bd883d173c..d474e405a16 100644 --- a/cli.py +++ b/cli.py @@ -12934,7 +12934,19 @@ def main( # Exit with error code if credentials or agent init fails sys.exit(1) else: - cli.show_banner() + # Single-query mode (`hermes chat -q "…"`): skip the welcome + # banner. Building the banner takes ~420 ms on cold start — + # ~200 ms of that is the version-update check, the rest is + # toolset / skill enumeration and Rich panel rendering. None + # of that is useful for a one-shot query: the user already + # picked the prompt, doesn't need a toolset reference, and + # gets the session ID + resume hint from + # ``_print_exit_summary()`` after the response prints. + # + # The fully-quiet ``-Q`` / ``--quiet`` machine-readable path + # above was already banner-free; this brings the human- + # facing single-query path in line so all non-interactive + # invocations are fast. _query_label = query or ("[image attached]" if single_query_images else "") if _query_label: cli.console.print(f"[bold blue]Query:[/] {_query_label}")