Explicit timeouts on every OpenAI and Gemini request (#153)
No AI client set a timeout: OpenAI's SDK waits 600s per attempt and retries twice (timeouts included); google-genai waits forever. A hung provider call had no upper bound, so recorrelation_sweep's 15-minute pipeline hold-back was a guess against an unbounded tail. - config: stt_timeout_seconds (120), openai_timeout_seconds (60), openai_max_retries (1), gemini_timeout_seconds (60). - app/internal/ai_clients.py builds every OpenAI/AsyncOpenAI client with them (transcription, extraction, embeddings, summarizer, vocabulary learner, trip chat). gemini.py's shared client gets HttpOptions(timeout=ms). - A timeout raises like any other provider error, so existing fallbacks are unchanged: rules-only correlation, rules decision on tiebreak, raw transcript on correction, ai_health "transient". - MIN_MINUTES_SINCE_PIPELINE_START is now derived from those timeouts (pipeline_worst_case_seconds, 3-scene budget + 2 min non-AI slack), floor 15: 21 min with the defaults. Loop warns if it reaches the scan window. - tests/test_ai_timeouts.py: client limits, a real hung-socket request that gives up in <5s, timeout fallback per tier, the derived bound, and a guard against any new OpenAI( outside ai_clients.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d57738a8f6
commit
278edf48dc
@@ -938,7 +938,7 @@ def _sync_extract(
|
||||
) -> list[dict]:
|
||||
"""Call GPT-4o-mini and return a list of scene dicts."""
|
||||
from app.config import settings
|
||||
from openai import OpenAI
|
||||
from app.internal.ai_clients import openai_client
|
||||
|
||||
if not settings.openai_api_key:
|
||||
logger.warning("OPENAI_API_KEY not set — intelligence extraction disabled.")
|
||||
@@ -956,7 +956,7 @@ def _sync_extract(
|
||||
)
|
||||
|
||||
try:
|
||||
client = OpenAI(api_key=settings.openai_api_key)
|
||||
client = openai_client()
|
||||
response = client.chat.completions.create(
|
||||
model="gpt-4o-mini",
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
@@ -985,13 +985,13 @@ def _sync_extract(
|
||||
def _sync_embed(text: str) -> Optional[list[float]]:
|
||||
"""Generate a text-embedding-3-small vector for semantic similarity."""
|
||||
from app.config import settings
|
||||
from openai import OpenAI
|
||||
from app.internal.ai_clients import openai_client
|
||||
|
||||
if not settings.openai_api_key:
|
||||
return None
|
||||
|
||||
try:
|
||||
client = OpenAI(api_key=settings.openai_api_key)
|
||||
client = openai_client()
|
||||
result = client.embeddings.create(model="text-embedding-3-small", input=text)
|
||||
return result.data[0].embedding
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user