mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-26 11:12:03 +00:00
feat(gateway): typed send-error classification (SendResult.error_kind) (#50342)
Add a platform-neutral send-failure vocabulary so consumers can branch on a typed category instead of substring-matching the raw provider message. - base.py: SEND_ERROR_KINDS + classify_send_error() (too_long / bad_format / forbidden / not_found / rate_limited / transient / unknown), and an optional SendResult.error_kind field (defaults None — fully backward compatible). - telegram.py: populate error_kind on send() failures; message_too_long keeps its existing error token plus error_kind='too_long'. Purely additive: no behavioral change to the existing degrade-and-deliver paths (MarkdownV2->plain-text fallback, overflow split, retry classification all untouched). 22 new tests + 210 adapter regression tests green.
This commit is contained in:
parent
6bbacc2238
commit
c0409a87ff
3 changed files with 244 additions and 2 deletions
|
|
@ -72,6 +72,7 @@ from gateway.platforms.base import (
|
|||
MessageType,
|
||||
ProcessingOutcome,
|
||||
SendResult,
|
||||
classify_send_error,
|
||||
cache_image_from_bytes,
|
||||
cache_audio_from_bytes,
|
||||
cache_video_from_bytes,
|
||||
|
|
@ -2763,6 +2764,7 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
except Exception as e:
|
||||
logger.error("[%s] Failed to send Telegram message: %s", self.name, e, exc_info=True)
|
||||
err_str = str(e).lower()
|
||||
error_kind = classify_send_error(e)
|
||||
# Message too long — content exceeded 4096 chars. Return failure so
|
||||
# stream consumer enters fallback mode and sends the remainder.
|
||||
if "message_too_long" in err_str or "too long" in err_str:
|
||||
|
|
@ -2770,7 +2772,7 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
"[%s] send() content too long, falling back to new-message continuation",
|
||||
self.name,
|
||||
)
|
||||
return SendResult(success=False, error="message_too_long")
|
||||
return SendResult(success=False, error="message_too_long", error_kind="too_long")
|
||||
# TimedOut usually means the request may have reached Telegram —
|
||||
# mark as non-retryable so _send_with_retry() doesn't re-send.
|
||||
# Exceptions: a wrapped ConnectTimeout (no connection established)
|
||||
|
|
@ -2780,7 +2782,12 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
is_timeout = (_to and isinstance(e, _to)) or "timed out" in err_str
|
||||
is_connect_timeout = self._looks_like_connect_timeout(e)
|
||||
is_pool_timeout = self._looks_like_pool_timeout(e)
|
||||
return SendResult(success=False, error=str(e), retryable=(is_connect_timeout or is_pool_timeout or not is_timeout))
|
||||
return SendResult(
|
||||
success=False,
|
||||
error=str(e),
|
||||
retryable=(is_connect_timeout or is_pool_timeout or not is_timeout),
|
||||
error_kind=error_kind,
|
||||
)
|
||||
|
||||
async def send_or_update_status(
|
||||
self,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue