Build: Release v2.80.28
This commit is contained in:
@@ -48,6 +48,19 @@ export class LMStudioStreamer implements IChatStreamer {
|
||||
signal: req.signal,
|
||||
});
|
||||
|
||||
// Bridge AbortSignal → prediction.cancel(): without this, an aborted
|
||||
// request keeps generating on the LM Studio server. The orphaned
|
||||
// prediction holds locks on the model handle, which is a known cause
|
||||
// of "lock() request could not be registered" on the very next
|
||||
// request — the reused handle is still bound to a dead prediction.
|
||||
const onAbort = () => {
|
||||
try { (prediction as any)?.cancel?.(); } catch { /* swallow — best effort */ }
|
||||
};
|
||||
if (req.signal) {
|
||||
if (req.signal.aborted) onAbort();
|
||||
else req.signal.addEventListener('abort', onAbort, { once: true });
|
||||
}
|
||||
|
||||
try {
|
||||
for await (const fragment of prediction as AsyncIterable<{ content: string }>) {
|
||||
if (req.signal?.aborted) return;
|
||||
@@ -59,6 +72,8 @@ export class LMStudioStreamer implements IChatStreamer {
|
||||
if (err?.name === 'AbortError') return;
|
||||
logError('LM Studio SDK chat stream failed.', { model: trimmedModel, error: err?.message ?? String(err) });
|
||||
throw err;
|
||||
} finally {
|
||||
req.signal?.removeEventListener?.('abort', onAbort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user