Files
openai--openai-agents-python/src/agents/models/_openai_retry.py
T
2026-07-13 12:39:17 +08:00

113 lines
3.5 KiB
Python

from __future__ import annotations
from openai import APIConnectionError, APITimeoutError
from ..retry import ModelRetryAdvice, ModelRetryAdviceRequest, ModelRetryNormalizedError
from ._retry_runtime import (
get_error_code as _get_error_code,
get_error_header as _get_header_value,
get_request_id as _get_request_id,
get_retry_after,
get_status_code as _get_status_code,
iter_error_chain as _iter_error_chain,
)
def _is_stateful_request(request: ModelRetryAdviceRequest) -> bool:
return bool(request.previous_response_id or request.conversation_id)
def _build_normalized_error(
error: Exception,
*,
retry_after: float | None,
) -> ModelRetryNormalizedError:
return ModelRetryNormalizedError(
status_code=_get_status_code(error),
error_code=_get_error_code(error),
message=str(error),
request_id=_get_request_id(error),
retry_after=retry_after,
is_abort=False,
is_network_error=any(
isinstance(candidate, APIConnectionError) for candidate in _iter_error_chain(error)
),
is_timeout=any(
isinstance(candidate, APITimeoutError) for candidate in _iter_error_chain(error)
),
)
def get_openai_retry_advice(request: ModelRetryAdviceRequest) -> ModelRetryAdvice | None:
error = request.error
if getattr(error, "unsafe_to_replay", False):
return ModelRetryAdvice(
suggested=False,
replay_safety="unsafe",
reason=str(error),
)
error_message = str(error).lower()
if (
"the request may have been accepted, so the sdk will not automatically "
"retry this websocket request." in error_message
):
return ModelRetryAdvice(
suggested=False,
replay_safety="unsafe",
reason=str(error),
)
retry_after = get_retry_after(error)
normalized = _build_normalized_error(error, retry_after=retry_after)
stateful_request = _is_stateful_request(request)
should_retry_header = _get_header_value(error, "x-should-retry")
if should_retry_header is not None:
header_value = should_retry_header.lower().strip()
if header_value == "true":
return ModelRetryAdvice(
suggested=True,
retry_after=retry_after,
replay_safety="safe",
reason=str(error),
normalized=normalized,
)
if header_value == "false":
return ModelRetryAdvice(
suggested=False,
retry_after=retry_after,
reason=str(error),
normalized=normalized,
)
if normalized.is_network_error or normalized.is_timeout:
return ModelRetryAdvice(
suggested=True,
retry_after=retry_after,
reason=str(error),
normalized=normalized,
)
if normalized.status_code in {408, 409, 429} or (
isinstance(normalized.status_code, int) and normalized.status_code >= 500
):
advice = ModelRetryAdvice(
suggested=True,
retry_after=retry_after,
reason=str(error),
normalized=normalized,
)
if stateful_request:
advice.replay_safety = "safe"
return advice
if retry_after is not None:
return ModelRetryAdvice(
retry_after=retry_after,
reason=str(error),
normalized=normalized,
)
return None