Files
OpenMAIC/lib/ai
RiverandXingJia He 1fe07df8b9 fix(ai): let LLM calls outlive undici's 300s headers timeout (#1404)
* fix(ai): let LLM calls outlive undici's 300s headers timeout

A non-streaming completion only receives response headers once the whole
completion exists, so undici's default 300 s headers timeout bounds total
generation time. Thinking models (GLM-5.x at effort=max, MiniMax M3, …)
routinely exceed that on large prompts — the request then dies with
"Cannot connect to API: Headers Timeout Error" at exactly 300 s and, with
maxRetries 0, the scene never generates (observed on a self-hosted
deployment with glm-5.2 scene generation).

Route every outbound LLM request through an undici Agent with a
15-minute headers/body timeout, attached at the shared transportFetch
seam so the OpenAI-compatible, native OpenAI/Responses, Azure,
Anthropic-compatible and Google transports all inherit it (same
lazy-import dispatcher pattern the Google proxy transport already
uses). Native transports now always install the shared transport
instead of only when the server injects a validating fetch.

* fix(ai): harden the LLM transport timeout fallback

Review follow-ups for the undici headers-timeout fix:

- getLlmDispatcher(): drop the cached promise on rejection so one
  transient undici import/Agent failure can't brick every later call;
  transportFetch falls back to the base transport (no dispatcher) when
  the dispatcher can't be built, warning once per failure episode
- bedrock: install fetch: transportFetch like every other transport
- google proxy: build ProxyAgent with the same headers/body timeout
  budget (http/https proxies; undici's Socks5ProxyAgent drops these
  options for socks5://)
- transportFetch no longer overwrites a caller-supplied dispatcher
- tests: dispatcher failure fallback + retry, bedrock transport,
  caller-dispatcher preservation, google proxy budget

---------

Co-authored-by: XingJia He <hexingjia@mobirit.com>
2026-09-11 02:48:35 +02:00
..