mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-21 10:22:18 +00:00
fix(agent): summarize structured provider error messages
This commit is contained in:
parent
620fd59b8e
commit
e4452ffb8a
2 changed files with 59 additions and 0 deletions
30
run_agent.py
30
run_agent.py
|
|
@ -1840,6 +1840,35 @@ class AIAgent:
|
|||
return detail
|
||||
return f"{detail}{hint}"
|
||||
|
||||
@staticmethod
|
||||
def _coerce_api_error_detail(value: Any) -> str:
|
||||
"""Return a display-safe string for structured provider error fields."""
|
||||
if isinstance(value, str):
|
||||
return value
|
||||
if isinstance(value, dict):
|
||||
for key in ("message", "detail", "error", "code", "type"):
|
||||
nested = value.get(key)
|
||||
if isinstance(nested, str) and nested.strip():
|
||||
return nested
|
||||
for key in ("message", "detail", "error", "code", "type"):
|
||||
if key in value:
|
||||
nested_detail = AIAgent._coerce_api_error_detail(value[key])
|
||||
if nested_detail:
|
||||
return nested_detail
|
||||
try:
|
||||
return json.dumps(value, ensure_ascii=False, sort_keys=True)
|
||||
except TypeError:
|
||||
return str(value)
|
||||
if isinstance(value, (list, tuple)):
|
||||
parts = [
|
||||
AIAgent._coerce_api_error_detail(item)
|
||||
for item in value
|
||||
]
|
||||
return "; ".join(part for part in parts if part)
|
||||
if value is None:
|
||||
return ""
|
||||
return str(value)
|
||||
|
||||
@staticmethod
|
||||
def _summarize_api_error(error: Exception) -> str:
|
||||
"""Extract a human-readable one-liner from an API error.
|
||||
|
|
@ -1879,6 +1908,7 @@ class AIAgent:
|
|||
if msg:
|
||||
status_code = getattr(error, "status_code", None)
|
||||
prefix = f"HTTP {status_code}: " if status_code else ""
|
||||
msg = AIAgent._coerce_api_error_detail(msg)
|
||||
return AIAgent._decorate_xai_entitlement_error(f"{prefix}{msg[:300]}")
|
||||
|
||||
# Fallback: truncate the raw string but give more room than 200 chars
|
||||
|
|
|
|||
|
|
@ -252,6 +252,35 @@ def test_summarize_api_error_decorates_xai_body_message():
|
|||
assert "X Premium+ does NOT include" in summary
|
||||
|
||||
|
||||
def test_summarize_api_error_handles_nested_provider_message():
|
||||
"""HF router may put a structured object in error.message."""
|
||||
from run_agent import AIAgent
|
||||
|
||||
class _NestedProviderErr(Exception):
|
||||
status_code = 400
|
||||
body = {
|
||||
"error": {
|
||||
"message": {
|
||||
"type": "Bad Request",
|
||||
"code": "context_length_exceeded",
|
||||
"message": (
|
||||
"This model's maximum context length is 262144 tokens. "
|
||||
"Please reduce the length of the messages."
|
||||
),
|
||||
"param": None,
|
||||
},
|
||||
"type": "invalid_request_error",
|
||||
"param": None,
|
||||
"code": None,
|
||||
}
|
||||
}
|
||||
|
||||
summary = AIAgent._summarize_api_error(_NestedProviderErr("400"))
|
||||
assert "HTTP 400" in summary
|
||||
assert "maximum context length is 262144 tokens" in summary
|
||||
assert "context_length_exceeded" not in summary
|
||||
|
||||
|
||||
def test_summarize_api_error_idempotent_for_entitlement_hint():
|
||||
"""Decorating twice must not double up the hint."""
|
||||
from run_agent import AIAgent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue