MQ-01: the Anthropic adapter used a default http.Client, so a 3xx from the
configured endpoint was followed and the x-api-key header resent to the
redirect target; net/http strips only its own sensitive headers. Both
adapters now use a client whose CheckRedirect returns ErrUseLastResponse,
so a 3xx comes back as an llm.ProviderError and nothing is requested again.
The OpenAI-compatible adapter gets the same change: it forwards configured
extra headers (which may carry a credential and which net/http does not
treat as sensitive) across hosts, and net/http keeps Authorization on a
same-host https-to-http redirect.
MQ-02: a delay-seconds Retry-After too large for time.Duration overflowed
into a negative wait. retryAfter now caps the value at the most whole
seconds a time.Duration holds (also for values beyond int64) and the
response still maps to ErrRateLimited.
Tests: TestRedirectIsNotFollowed (302 to a second server, which must get
no request) and TestRateLimitedHugeRetryAfterIsCapped in both packages,
plus huge-number cases in TestRetryAfter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The OpenAI adapter's redactedError had no GoString, so %#v printed its
fields, including the raw API key. Add GoString returning the redacted
text, matching the Anthropic adapter; redactedJoin inherits it.
Add TestRedactedErrorsFormatWithoutKey to both adapters, formatting
redactedError, redactedJoin and transportFailure with %v, %+v and %#v.
llm.ProviderError and llm.RateLimitedError keep no secret and are
already covered by TestTypedErrorsDoNotKeepSecret.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>