fix(llm): honor DeepSeek SSE keep-alives

This commit is contained in:
fz
2026-08-04 11:48:34 +08:00
parent 804b724202
commit cd6bd5c188
17 changed files with 134 additions and 35 deletions

View File

@@ -72,6 +72,8 @@ export interface IdleWatchdog {
* @returns the iterator's next result.
*/
next<T>(iterator: AsyncIterator<T>): Promise<IteratorResult<T>>
/** Rearm an outstanding demand after transport activity that yields no iterator value; otherwise a no-op. */
pulse(): void
/** Clear an armed timer; safe to call once at the owning stream's exit. */
[Symbol.dispose](): void
}
@@ -135,15 +137,20 @@ export function idleWatchdog(
let outstanding = false
let disposed = false
const arm = (): void => {
if (timer !== undefined) clearTimeout(timer)
timer = setTimeout(() => {
timeout.abort(new TimeoutReason(code, timeoutMs))
}, timeoutMs)
}
return {
signal,
async next<T>(iterator: AsyncIterator<T>): Promise<IteratorResult<T>> {
if (disposed) throw new Error('idleWatchdog is disposed')
if (outstanding) throw new Error('idleWatchdog next is already outstanding')
outstanding = true
timer = setTimeout(() => {
timeout.abort(new TimeoutReason(code, timeoutMs))
}, timeoutMs)
arm()
try {
return await iterator.next()
} finally {
@@ -152,6 +159,10 @@ export function idleWatchdog(
outstanding = false
}
},
pulse(): void {
if (disposed || !outstanding) return
arm()
},
[Symbol.dispose](): void {
if (disposed) return
disposed = true