mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-24 18:50:15 +00:00
stage-341: apply Opus SHOULD-FIX (it i18n + short-circuit logger.debug + docstring)
Opus advisor pass on stage-341 found three surgical items: 1. static/i18n.js:it — PR #2064 branched before stage-340 landed the 'it' locale (#2067), missing 9 session_*worktree* keys. Mechanical mirror of en/ja position. Italian falls back to English silently without this fix. 2. api/streaming.py — PR #2107's new break short-circuit was silent in both the aux and agent title-generation paths. Added logger.debug calls before each break so production logs surface the exit shape. 3. api/streaming.py — Expanded _title_should_skip_remaining_attempts docstring to document the membership criterion explicitly (vs the implicit reasoning-only-burn case it ships with today). Future additions (llm_safety_blocked, llm_oauth_quota) have a clear inclusion test. CHANGELOG updated under the Stage-341 maintainer fixes section to mirror the stage-340 pattern. All targeted tests pass (57/57 in the affected modules).
This commit is contained in:
@@ -16,6 +16,11 @@
|
||||
|
||||
- **`docs/rfcs/README.md`** — Added a single bullet to the conventions block clarifying that RFCs are design directions, not invitations to file implementation PRs against fragments. Implementation slices need maintainer confirmation in the tracking issue first. Applied alongside PR #2105 to head off the speculative-fragment pattern we just had to put on hold with PR #2071 (well-written 651-LOC collector with no callers). ~6 LOC.
|
||||
|
||||
- **`static/i18n.js:it` block** — Opus SHOULD-FIX from stage-341 review: PR #2064 was branched before stage-340 landed the `it` locale (#2067), so the 9 new `session_*worktree*` keys were missing for Italian users. Mechanical add inside the `it:` block at the parallel position to en/ja. Falls back to English silently without this fix; with this fix, Italian users see the worktree-retention reassurance copy in their locale. Parallels the stage-340 `cron_toast_notifications_*` fix exactly. ~9 LOC.
|
||||
|
||||
- **`api/streaming.py` short-circuit observability** — Opus SHOULD-FIX from stage-341 review: PR #2107's new `_title_should_skip_remaining_attempts` short-circuit `break` was silent in both the aux and agent title-generation paths. Added a `logger.debug` call before each `break` so production logs surface why the prompt-iteration loop exited early (nesquena flagged this as non-blocking; landed as polish in the same release). Also expanded the function's docstring to document the membership criterion explicitly so future additions (`llm_safety_blocked`, `llm_oauth_quota`, etc.) have a clear inclusion test. ~16 LOC.
|
||||
|
||||
|
||||
## [v0.51.47] — 2026-05-11 — Release W (4-PR contributor batch — per-cron toast toggle + Italian locale + stale-gateway agent-health fix + CI/console hygiene)
|
||||
|
||||
### Added
|
||||
|
||||
+23
-5
@@ -896,11 +896,21 @@ def _title_retry_status(status: str) -> bool:
|
||||
|
||||
|
||||
def _title_should_skip_remaining_attempts(status: str) -> bool:
|
||||
# When a reasoning model burns its budget on hidden reasoning,
|
||||
# additional prompts against the same model will hit the same wall.
|
||||
# Short-circuit the prompt-iteration loop so we don't issue a second
|
||||
# full-budget LLM call (and twice the GPU/credit burn) only to land in
|
||||
# the same fallback path. See issue #2083.
|
||||
"""Statuses where re-issuing the next prompt against the same model
|
||||
produces the same failing shape (model burned its budget on hidden
|
||||
reasoning, hit a hard provider gate, etc.).
|
||||
|
||||
Short-circuit the prompt-iteration loop so we don't issue a second
|
||||
full-budget LLM call (and twice the GPU/credit burn) only to land in
|
||||
the same fallback path. See issue #2083.
|
||||
|
||||
Add a status here only when retrying the next prompt is provably
|
||||
wasted work (single-call signal already establishes that the next
|
||||
call will return the same shape). Length-truncation WITHOUT
|
||||
reasoning is NOT in the set — that's legitimately recoverable by
|
||||
a larger budget on a different prompt and stays in
|
||||
:func:`_title_retry_status`.
|
||||
"""
|
||||
return status in {
|
||||
'llm_empty_reasoning',
|
||||
'llm_empty_reasoning_aux',
|
||||
@@ -1010,6 +1020,10 @@ def generate_title_raw_via_aux(
|
||||
# the next prompt against the same model produces the same shape.
|
||||
# Short-circuit to the local fallback path (#2083).
|
||||
if _title_should_skip_remaining_attempts(last_status):
|
||||
logger.debug(
|
||||
"Aux title generation short-circuiting after %s (reasoning-only response).",
|
||||
last_status,
|
||||
)
|
||||
break
|
||||
return None, last_status
|
||||
except Exception as e:
|
||||
@@ -1114,6 +1128,10 @@ def generate_title_raw_via_agent(agent, user_text: str, assistant_text: str) ->
|
||||
# the next prompt against the same model produces the same shape.
|
||||
# Short-circuit to the local fallback path (#2083).
|
||||
if _title_should_skip_remaining_attempts(last_status):
|
||||
logger.debug(
|
||||
"Agent title generation short-circuiting after %s (reasoning-only response).",
|
||||
last_status,
|
||||
)
|
||||
break
|
||||
return None, last_status
|
||||
except Exception as e:
|
||||
|
||||
@@ -1519,8 +1519,10 @@ const LOCALES = {
|
||||
session_archive: 'Archivia conversazione',
|
||||
session_restore: 'Ripristina conversazione',
|
||||
session_archive_desc: 'Nascondi questa conversazione fino a mostrare archiviate',
|
||||
session_archive_worktree_desc: 'Nascondi questa conversazione; mantieni il suo worktree su disco',
|
||||
session_restore_desc: 'Riporta questa conversazione nella lista principale',
|
||||
session_archived: 'Sessione archiviata',
|
||||
session_archived_worktree: 'Sessione archiviata. Il worktree rimane su disco.',
|
||||
session_restored: 'Sessione ripristinata',
|
||||
session_archive_failed: 'Archiviazione fallita: ',
|
||||
session_duplicate: 'Duplica conversazione',
|
||||
@@ -1531,6 +1533,11 @@ const LOCALES = {
|
||||
session_stop_response_desc: 'Annulla la risposta in corso per questa conversazione',
|
||||
session_delete: 'Elimina conversazione',
|
||||
session_delete_desc: 'Rimuovi permanentemente questa conversazione',
|
||||
session_delete_confirm: 'Eliminare questa conversazione?',
|
||||
session_delete_worktree_desc: 'Elimina solo la conversazione di WebUI; mantieni il worktree su disco',
|
||||
session_delete_worktree_confirm: (path) => `Eliminare questa conversazione? Il worktree in ${path} rimarrà su disco.`,
|
||||
session_deleted: 'Conversazione eliminata',
|
||||
session_deleted_worktree: 'Conversazione eliminata. Il worktree rimane su disco.',
|
||||
session_select_mode: 'Seleziona',
|
||||
session_select_mode_desc: 'Seleziona conversazioni per gestione in blocco',
|
||||
session_select_all: 'Seleziona tutto',
|
||||
@@ -1541,6 +1548,8 @@ const LOCALES = {
|
||||
session_batch_move: 'Sposta nel progetto',
|
||||
session_batch_delete_confirm: 'Eliminare {0} conversazioni?',
|
||||
session_batch_archive_confirm: 'Archiviare {0} conversazioni?',
|
||||
session_batch_delete_worktree_confirm: 'Eliminare {0} conversazioni? {1} conversazioni con worktree lasceranno le loro directory worktree su disco.',
|
||||
session_batch_archive_worktree_confirm: 'Archiviare {0} conversazioni? {1} conversazioni con worktree manterranno le loro directory worktree su disco.',
|
||||
session_no_selection: 'Nessuna conversazione selezionata',
|
||||
// settings panel
|
||||
settings_heading_title: 'Pannello di Controllo',
|
||||
|
||||
Reference in New Issue
Block a user