mirror of
https://github.com/langgenius/dify.git
synced 2026-07-14 17:07:03 +08:00
The thread-based FirstTokenWatchdog could never fire in production: the plugin daemon withholds the SSE response headers until the model's first token, so the whole time-to-first-token is spent inside httpx Client.stream() waiting for headers -- before the watchdog is armed. It only ever measured headers->first-frame (~0s) and was disarmed by the first frame. Replace the watchdog with httpx's per-request read timeout set to the first-token budget. httpcore applies read to both the header wait and each body read, and the daemon sends no heartbeat before the first token, so it measures time-to-first-token directly. A pre-first-token ReadTimeout with the gate enabled becomes FirstTokenTimeoutError; anything else (inter-token stall, gate off, other transport errors) stays a normal transport error. Deletes the entire watchdog subsystem (timer, lock, socket-abort, content-detection); the ContextVar plumbing and producer side are unchanged.