Retry, backoff and default Generate timeout #48

Member

Task 1a882923-fdb4-4576-ab82-9529e9974b26.

Retrying Provider: at most two retries for rate limit, timeout, and 5xx; never auth or 4xx; RetryAfter capped at 20s; deadline respected; Generate defaults to 60s. FromSettings returns the wrapper. Head bcdea85a2d.

Task 1a882923-fdb4-4576-ab82-9529e9974b26. Retrying Provider: at most two retries for rate limit, timeout, and 5xx; never auth or 4xx; RetryAfter capped at 20s; deadline respected; Generate defaults to 60s. FromSettings returns the wrapper. Head bcdea85a2dccf0e79972177a9c5facbb6fdc7880.
dev_agent added 2 commits 2026-10-04 10:50:15 -04:00
llm.NewRetrying wraps a Provider and retries ErrRateLimited, ErrTimeout
and 5xx ErrProvider at most twice. A rate limit waits RetryAfter, capped
at 20 s; other retries use jittered exponential backoff. ErrAuth, 4xx and
other errors are never retried, and no retry is made whose wait would not
end before the caller's context deadline. Generate gets a 60 s per-attempt
timeout when Request.Timeout is 0.

Maestro task: 1a882923-fdb4-4576-ab82-9529e9974b26

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wire retrying Provider into presets.FromSettings
CI / ci (pull_request) Successful in 1m31s
CI / ci (push) Successful in 1m32s
bcdea85a2d
FromSettings now returns llm.NewRetrying around the configured adapter,
so every Provider it builds retries transient Generate failures and gets
the default timeout; ListModels and Verify pass through.

The test recording transport now answers 400 instead of failing the
round trip: the ollama adapter reports a transport failure as
ErrTimeout, which is retried, so the helper would see three requests.

Tests: a 429 then 200 succeeds on the second request; exhausted retries
return ErrProvider after MaxRetries+1 requests with no key in any error.

Maestro task: 1a882923-fdb4-4576-ab82-9529e9974b26

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dev_agent added 1 commit 2026-10-04 10:54:24 -04:00
Bound whole retrying Generate call by one deadline
CI / ci (push) Successful in 1m29s
CI / ci (pull_request) Successful in 1m33s
d90886ddc2
Request.Timeout, or the 60-second default, now sets a single context
deadline covering every attempt and wait, instead of restarting for
each attempt. A shorter caller deadline still wins; attempts receive
Timeout 0 so adapters do not restart the clock. A negative Timeout is
left for the wrapped Provider to reject with its key redaction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dev_agent added 1 commit 2026-10-04 10:59:24 -04:00
Do not retry an HTTP 408; lock retry cap and timeout values
CI / ci (push) Successful in 1m30s
Independent review Codex gpt-6-sol high: APPROVED (0 findings)
CI / ci (pull_request) Successful in 1m30s
f8e975e284
The OpenAI and Anthropic adapters now report an HTTP 408 as
llm.TimeoutStatusError, which still matches llm.ErrTimeout but carries
its status. Retrying no longer retries any error carrying a 4xx status,
so a vendor's 408 is returned at once while a transport timeout, which
has no status, is still retried.

Tests: 408 (bare and wrapped) is not retried and a transport timeout is;
FromSettings integration cases for an OpenAI and Anthropic 408 and an
OpenAI transport timeout; the cap and default-timeout tests assert the
literal 20 s and 60 s instead of the constants they lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent left a comment
Member

Independent review — Codex gpt-6-sol, reasoning high

Verdict: APPROVED
Reviewed SHA: f8e975e284834ecdc40c98cd5f88dae6863f06ba

{
  "verdict": "APPROVED",
  "reviewed_sha": "f8e975e284834ecdc40c98cd5f88dae6863f06ba",
  "summary": "The retry rules, 20 s cap, whole-call deadline, and per-request timeout match the done-condition. FromSettings returns the wrapper; 401, other 4xx, and HTTP 408 are not retried, while transport timeouts are. Errors redact the key, no dependency was added, and the scripted tests exercise the behavior. gofmt, go vet, and go test -race -count=1 ./... passed.",
  "findings": []
}

Posted unaltered by review_agent. This is transport, not a second review.

## Independent review — Codex `gpt-6-sol`, reasoning high Verdict: **APPROVED** Reviewed SHA: `f8e975e284834ecdc40c98cd5f88dae6863f06ba` ```json { "verdict": "APPROVED", "reviewed_sha": "f8e975e284834ecdc40c98cd5f88dae6863f06ba", "summary": "The retry rules, 20 s cap, whole-call deadline, and per-request timeout match the done-condition. FromSettings returns the wrapper; 401, other 4xx, and HTTP 408 are not retried, while transport timeouts are. Errors redact the key, no dependency was added, and the scripted tests exercise the behavior. gofmt, go vet, and go test -race -count=1 ./... passed.", "findings": [] } ``` --- Posted unaltered by `review_agent`. This is transport, not a second review.
approver_agent merged commit b347e1c911 into feature/5dd6e253-cc9b-41f3-9091-bb834f7a373a-llm-provider-layer 2026-10-04 11:02:56 -04:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Maniacs_Mansion/MealQuest#48