Skip to content

Retry transient HTTP failures + require all properties in strict schemas#288

Merged
Kamilbenkirane merged 3 commits into
mainfrom
feat/celeste-hardening
Jun 19, 2026
Merged

Retry transient HTTP failures + require all properties in strict schemas#288
Kamilbenkirane merged 3 commits into
mainfrom
feat/celeste-hardening

Conversation

@Kamilbenkirane

Copy link
Copy Markdown
Member

Two independent primitive-hardening fixes, one commit each.

feat(http) — retry transient HTTP failures

HTTPClient.post/get/post_multipart now retry transient network failures (httpx timeouts, connection/read errors) and retryable status codes (408/429/500/502/503/504) with bounded exponential backoff (MAX_RETRIES=2), then fail hard. This matches the retry the OpenAI and Anthropic Python SDKs ship by default — and httpx's built-in transport retries only cover connection failures, not read timeouts. Streaming requests are unchanged.

fix(structured-outputs) — require all properties in strict schemas

StrictJsonSchemaGenerator forced additionalProperties: false but never required. OpenAI and xAI strict mode require every property in required, and Pydantic omits any field that has a default — so a model with defaulted fields is rejected (400, "missing required"). The generator now forces required = list(properties) on every object, completing the strict transform for OpenAI, xAI, and Anthropic at once.

Both changes carry unit tests; the full unit suite plus ruff, mypy, and bandit pass (via pre-commit).

Add bounded retry with exponential backoff to HTTPClient.post/get/post_multipart on
transient network errors (httpx timeouts, connection/read errors) and retryable status
codes (408/429/500/502/503/504); MAX_RETRIES=2 by default, then re-raise. Brings transport
resilience in line with the openai/anthropic SDKs. Streaming is unchanged.
StrictJsonSchemaGenerator set additionalProperties:false but never required, so schemas
with defaulted fields (which Pydantic omits from required) 400 on OpenAI and xAI strict
mode. Force required = all properties for every object.
@claude

claude Bot commented Jun 19, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Collapse the five near-identical TestHTTPClientRetry cases into one
parametrized test (transient/status retried, non-retryable, exhausted)
plus the reraise case.
@Kamilbenkirane Kamilbenkirane merged commit 6afb7ed into main Jun 19, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant