SIGN IN SIGN UP

internal/swaputil: OpenAI-compatible error bodies (#1038)

Error responses used a string-valued "error" field, so OpenAI clients
that read body["error"]["message"] hit a string where they expected an
object. Home Assistant's OpenAI-style conversation integration turns
that into an opaque 500 instead of a retryable "server busy" signal
when concurrencyLimit sheds a request.

Every JSON error body now uses the OpenAI envelope, with error.type and
error.code derived from the HTTP status:

  {"src":"llama-swap",
   "error":{"message":"Too many requests","type":"rate_limit_error",
            "param":null,"code":"concurrency_limit"}}

- add ErrorEnvelope/ErrorDetail and NewErrorEnvelope() in swaputil
- render SendResponse's JSON branch and ConcurrencyLimitError.Body()
  through the envelope, keeping status codes and Retry-After unchanged
- route the two remaining http.Error() call sites (process not ready,
  peer proxy failure) through SendResponse so they use the envelope too
- keep the top-level "src" marker and the text/plain and text/html
  response formats as they were

fix: #1037

Co-authored-by: Claude <noreply@anthropic.com>
B
Benson Wong committed
cb536168c48976815a658e4e3db381774242e16f
Parent: 23c28fe
Committed by GitHub <noreply@github.com> on 8/22/2026, 3:04:51 PM