HERMES-GIELIE/api
nesquena-hermes e20eb2c784 fix: skip budget-doubling title retry for reasoning-only responses (#2083)
Reasoning models (Qwen3-thinking via LM Studio, DeepSeek-R1, Kimi-K2,
etc.) can burn their entire output budget on hidden reasoning tokens and
emit no visible content. The previous title-generation retry path
classified that as llm_length and doubled the budget — but the second
call produces the same shape, so the retry only doubled the GPU/credit
burn. Repeated across the two prompts in _title_prompts() this came to
~3000 reasoning tokens of GPU work per new chat. On local LM Studio
servers behind a custom: provider (where is_lmstudio=False means
reasoning_effort: none never reaches the model) it manifested as the GPU
never going idle after a prompt.

Fix:
  - _extract_title_response: classify reasoning-bearing empty responses
    as llm_empty_reasoning regardless of finish_reason. The presence of
    reasoning_content is the diagnostic signal, not finish_reason.
  - _title_retry_status: drop llm_empty_reasoning from the retry set.
    Length-truncated responses WITHOUT reasoning still retry (those are
    legitimately recoverable by a larger budget).
  - Add _title_should_skip_remaining_attempts() and break out of the
    prompt-iteration loop on empty-reasoning. A second prompt against
    the same model would produce the same shape.
  - Falls through to _fallback_title_from_exchange for a local-summary
    title.

Tests updated to invert the previous reasoning-retry assertions:
  - test_aux_short_circuits_on_empty_reasoning_without_retrying
  - test_aux_still_retries_finish_length_without_reasoning
  - test_agent_route_short_circuits_on_empty_reasoning_without_retrying
  - test_agent_route_still_retries_finish_length_without_reasoning

Companion agent-side work (LM Studio classifier for custom: providers)
is tracked separately on the hermes-agent side; this WebUI fix is the
belt-and-braces guard so the loop stops regardless of agent classifier
state.

Reported by @darkopetrovic. Closes #2083.

Co-authored-by: darkopetrovic <darkopetrovic@users.noreply.github.com>
(cherry picked from commit efeae4a86e377069c0f09d140429ecb111a8dd1a)
2026-05-12 00:04:11 +00:00
..
__init__.py
agent_health.py fix(agent-health): treat stale running gateway as unknown 2026-05-11 23:13:09 +00:00
agent_sessions.py fix: align fork lineage projection paths 2026-05-11 17:15:22 +08:00
auth.py fix(stage-326): preserve SESSION_TTL constant + reconcile #1957 tests 2026-05-09 18:33:28 +00:00
background.py
clarify.py
commands.py fix(security): drop unsafe-eval + add jsdelivr to CSP, sanitize plugin error 2026-05-11 17:53:02 +00:00
compression_anchor.py Refactor compression anchor visibility helpers 2026-05-11 20:56:30 +08:00
config.py Fix custom provider name slugs with ports 2026-05-11 17:24:53 +08:00
dashboard_probe.py feat: link official Hermes dashboard 2026-05-05 01:23:55 +00:00
extensions.py Opus pre-release follow-ups for PR #1445 2026-05-02 03:49:40 +00:00
gateway_watcher.py
goals.py fix(i18n): localize /goal runtime status strings 2026-05-10 15:21:24 +08:00
helpers.py fix: add cdn.jsdelivr.net to CSP connect-src to allow xterm source map fetches 2026-05-07 20:42:55 +00:00
kanban_bridge.py stage-315 absorb: document handle_kanban_* three-valued return contract 2026-05-07 18:52:01 +00:00
metering.py fix: show TPS in assistant message headers 2026-05-04 21:26:43 +00:00
models.py Add worktree-backed session creation 2026-05-11 12:12:40 +08:00
oauth.py fix(oauth): serialize Anthropic env fallback reads 2026-05-07 02:47:19 +00:00
onboarding.py Fix Xiaomi API key env detection 2026-05-11 07:33:52 +08:00
profiles.py Fix HERMES_HOME skill cache patching 2026-05-11 19:12:02 +08:00
providers.py fix(providers): log warning when custom provider entry yields empty slug 2026-05-11 17:30:56 +00:00
request_diagnostics.py fix: add request wedge diagnostics 2026-05-08 15:37:08 +00:00
rollback.py v0.50.255: Opus follow-ups (4 fixes) + CHANGELOG 2026-05-01 17:19:53 +00:00
routes.py feat(i18n): add Italian (it) locale 2026-05-11 23:13:55 +00:00
session_ops.py
session_recovery.py Merge PR #2059 into stage-339 2026-05-11 17:43:58 +00:00
startup.py
state_sync.py
streaming.py fix: skip budget-doubling title retry for reasoning-only responses (#2083) 2026-05-12 00:04:11 +00:00
system_health.py feat: add VPS resource health panel 2026-05-05 17:30:56 +00:00
terminal.py
turn_journal.py fix: address turn journal lifecycle review 2026-05-11 17:16:43 +02:00
updates.py fix: normalize update banner repository URLs 2026-05-05 08:29:00 -07:00
upload.py
workspace.py fix: preserve inaccessible workspace entries 2026-05-07 16:56:48 +00:00
worktrees.py Add worktree-backed session creation 2026-05-11 12:12:40 +08:00