-
Notifications
You must be signed in to change notification settings - Fork 52.8k
feat(display): add suppress_retry_status platform config flag #32569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2884,6 +2884,38 @@ def _should_emit_quiet_tool_messages(self) -> bool: | |
| and getattr(self, "platform", "") == "cli" | ||
| ) | ||
|
|
||
| def _should_suppress_retry_status(self) -> bool: | ||
| """Return True when retry/empty-response status bubbles should be suppressed. | ||
|
|
||
| Reads ``display.platforms.<platform>.suppress_retry_status`` from config. | ||
| Cached per agent instance. | ||
| """ | ||
| cached = getattr(self, "_suppress_retry_status_cached", None) | ||
| if cached is not None: | ||
| return cached | ||
| try: | ||
| from gateway.display_config import resolve_display_setting | ||
| from hermes_cli.config import load_config as _load_cfg | ||
| cfg = _load_cfg() or {} | ||
| platform_key = (self.platform or "").lower().strip() or "cli" | ||
| result = bool( | ||
| resolve_display_setting(cfg, platform_key, "suppress_retry_status", False) | ||
| ) | ||
| except Exception: | ||
| result = False | ||
| self._suppress_retry_status_cached = result | ||
| return result | ||
|
|
||
| def _emit_retry_status(self, message: str) -> None: | ||
| """Emit a retry/empty-response/fallback status bubble, if not suppressed. | ||
|
|
||
| No-op when ``suppress_retry_status`` is enabled for the active platform. | ||
| Otherwise identical to ``_emit_status``. | ||
| """ | ||
| if self._should_suppress_retry_status(): | ||
| return | ||
| self._emit_status(message) | ||
|
|
||
| def _emit_status(self, message: str) -> None: | ||
| """Emit a lifecycle status message to both CLI and gateway channels. | ||
|
|
||
|
|
@@ -15091,7 +15123,7 @@ def _stop_spinner(): | |
| "Empty response after tool calls — nudging model " | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Current main no longer executes this retry block from |
||
| "to continue processing" | ||
| ) | ||
| self._emit_status( | ||
| self._emit_retry_status( | ||
| "⚠️ Model returned empty after tool calls — " | ||
| "nudging to continue" | ||
| ) | ||
|
|
@@ -15137,7 +15169,7 @@ def _stop_spinner(): | |
| "prefilling to continue (%d/2)", | ||
| self._thinking_prefill_retries, | ||
| ) | ||
| self._emit_status( | ||
| self._emit_retry_status( | ||
| f"↻ Thinking-only response — prefilling to continue " | ||
| f"({self._thinking_prefill_retries}/2)" | ||
| ) | ||
|
|
@@ -15173,7 +15205,7 @@ def _stop_spinner(): | |
| "retry %d/3 (model=%s)", | ||
| self._empty_content_retries, self.model, | ||
| ) | ||
| self._emit_status( | ||
| self._emit_retry_status( | ||
| f"⚠️ Empty response from model — retrying " | ||
| f"({self._empty_content_retries}/3)" | ||
| ) | ||
|
|
@@ -15192,13 +15224,13 @@ def _stop_spinner(): | |
| self._empty_content_retries, self.model, | ||
| self.provider, | ||
| ) | ||
| self._emit_status( | ||
| self._emit_retry_status( | ||
| "⚠️ Model returning empty responses — " | ||
| "switching to fallback provider..." | ||
| ) | ||
| if self._try_activate_fallback(): | ||
| self._empty_content_retries = 0 | ||
| self._emit_status( | ||
| self._emit_retry_status( | ||
| f"↻ Switched to fallback: {self.model} " | ||
| f"({self.provider})" | ||
| ) | ||
|
|
@@ -15232,7 +15264,7 @@ def _stop_spinner(): | |
| "after exhausting retries and fallback. " | ||
| "Reasoning: %s", reasoning_preview, | ||
| ) | ||
| self._emit_status( | ||
| self._emit_retry_status( | ||
| "⚠️ Model produced reasoning but no visible " | ||
| "response after all retries. Returning empty." | ||
| ) | ||
|
|
@@ -15244,7 +15276,7 @@ def _stop_spinner(): | |
| self._empty_content_retries, self.model, | ||
| self.provider, | ||
| ) | ||
| self._emit_status( | ||
| self._emit_retry_status( | ||
| "❌ Model returned no content after all retries" | ||
| + (" and fallback attempts." if self._fallback_chain else | ||
| ". No fallback providers configured.") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suppresses the diagnostic for every blank post-API response, including genuine degraded failures. Current main distinguishes intentional silence via exact
NO_REPLY/[SILENT]markers ingateway/response_filters.py; preserving that distinction avoids silently hiding malformed or failed model output.