fix(llm): add per-turn model request timeout so stalled streams fail fast and retry

This commit is contained in:
Ahmed Allam
2026-07-17 18:40:23 -07:00
committed by Ahmed Allam
parent 9aa151c687
commit 3bb95ab43d
9 changed files with 77 additions and 4 deletions
+13
View File
@@ -21,6 +21,19 @@ if TYPE_CHECKING:
from strix.config.settings import Settings
def request_timeout_extra_args(timeout_s: float | None) -> dict[str, float] | None:
"""Per-request model timeout (connect + read/inactivity) as ``extra_args``.
Restores pre-v1 behavior: a stalled model stream trips this timeout and is
retried by ``DEFAULT_MODEL_RETRY`` instead of hanging the agent indefinitely.
The value is forwarded to the underlying ``responses.create`` /
``chat.completions.create`` / ``litellm.acompletion`` call.
"""
if not timeout_s or timeout_s <= 0:
return None
return {"timeout": float(timeout_s)}
def _retry_statusless_provider_errors(context: RetryPolicyContext) -> bool:
"""Retry statusless provider errors (e.g. mid-stream quota/billing), but not aborts."""
normalized = context.normalized
+3
View File
@@ -12,6 +12,7 @@ from strix.config.models import (
DEFAULT_MODEL_RETRY,
is_known_openai_bare_model,
model_supports_reasoning,
request_timeout_extra_args,
)
from strix.core.sessions import scrub_images_from_items
@@ -126,11 +127,13 @@ def make_model_settings(
*,
model_name: str,
force_required_tool_choice: bool = False,
request_timeout: float | None = None,
) -> ModelSettings:
model_settings = ModelSettings(
parallel_tool_calls=False,
retry=DEFAULT_MODEL_RETRY,
include_usage=True,
extra_args=request_timeout_extra_args(request_timeout),
)
if (
reasoning_effort is not None
+1
View File
@@ -215,6 +215,7 @@ async def run_strix_scan(
settings.llm.reasoning_effort,
model_name=resolved_model,
force_required_tool_choice=settings.llm.force_required_tool_choice,
request_timeout=settings.llm.timeout,
)
run_config = RunConfig(
model=resolved_model,
+6 -1
View File
@@ -16,6 +16,7 @@ from strix.config.models import (
DEFAULT_MODEL_RETRY,
StrixProvider,
configure_sdk_model_defaults,
request_timeout_extra_args,
)
from strix.report.state import get_global_report_state
@@ -310,7 +311,11 @@ async def check_duplicate(
response = await model.get_response(
system_instructions=DEDUPE_SYSTEM_PROMPT,
input=user_msg,
model_settings=ModelSettings(retry=DEFAULT_MODEL_RETRY, include_usage=True),
model_settings=ModelSettings(
retry=DEFAULT_MODEL_RETRY,
include_usage=True,
extra_args=request_timeout_extra_args(settings.llm.timeout),
),
tools=[],
output_schema=None,
handoffs=[],