

























@@ -205,15 +205,35 @@ export function streamWithIdleTimeout(
205205onIdleTimeout?: (error: Error) => void,
206206): StreamFn {
207207return (model, context, options) => {
208-const maybeStream = baseFn(model, context, options);
209-210208const createIdleTimeoutError = () =>
211209new Error(`LLM idle timeout (${Math.floor(timeoutMs / 1000)}s): no response from model`);
212210211+const streamAbortController = new AbortController();
212+const sourceSignal = options?.signal;
213+const abortStream = (reason?: unknown) => {
214+if (!streamAbortController.signal.aborted) {
215+streamAbortController.abort(reason);
216+}
217+};
218+const abortFromSourceSignal = () => abortStream(sourceSignal?.reason);
219+if (sourceSignal?.aborted) {
220+abortFromSourceSignal();
221+} else {
222+sourceSignal?.addEventListener("abort", abortFromSourceSignal, { once: true });
223+}
224+const cleanupSourceSignal = () => {
225+sourceSignal?.removeEventListener("abort", abortFromSourceSignal);
226+};
227+const wrappedOptions = {
228+ ...(options ?? {}),
229+signal: streamAbortController.signal,
230+} as typeof options;
231+213232const createTimeoutPromise = (setTimer: (timer: NodeJS.Timeout) => void): Promise<never> => {
214233return new Promise((_, reject) => {
215234const timer = setTimeout(() => {
216235const error = createIdleTimeoutError();
236+abortStream(error);
217237onIdleTimeout?.(error);
218238reject(error);
219239}, timeoutMs);
@@ -222,6 +242,14 @@ export function streamWithIdleTimeout(
222242});
223243};
224244245+let maybeStream: ReturnType<StreamFn>;
246+try {
247+maybeStream = baseFn(model, context, wrappedOptions);
248+} catch (error) {
249+cleanupSourceSignal();
250+throw error;
251+}
252+225253const wrapStream = (stream: ReturnType<typeof streamSimple>) => {
226254const originalAsyncIterator = stream[Symbol.asyncIterator].bind(stream);
227255(stream as { [Symbol.asyncIterator]: typeof originalAsyncIterator })[Symbol.asyncIterator] =
@@ -252,6 +280,7 @@ export function streamWithIdleTimeout(
252280253281if (result.done) {
254282clearTimer();
283+cleanupSourceSignal();
255284return result;
256285}
257286@@ -264,10 +293,12 @@ export function streamWithIdleTimeout(
264293},
265294onReturn(streamIterator) {
266295clearTimer();
296+cleanupSourceSignal();
267297return streamIterator.return?.() ?? Promise.resolve({ done: true, value: undefined });
268298},
269299onThrow(streamIterator, error) {
270300clearTimer();
301+cleanupSourceSignal();
271302return streamIterator.throw?.(error) ?? Promise.reject(error);
272303},
273304});
@@ -297,6 +328,7 @@ export function streamWithIdleTimeout(
297328},
298329(error) => {
299330clearStreamPromiseTimer();
331+cleanupSourceSignal();
300332throw error;
301333},
302334);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。