feat: 强制停止AI回复 - 真正中止Ollama接口请求
- ollama-api.js: chatStream 新增 AbortController 参数,同时中止 fetch 和 reader - input-area.js: 发送按钮流式时变为停止按钮(红色方块),点击立即 abort - abort 时保留已生成内容,标记 [已停止] - 停止按钮带脉冲动画,视觉反馈明确 - 真正的接口级别终止:fetch abort + reader.cancel 双重保险
This commit is contained in:
+19
-3
@@ -69,8 +69,10 @@ export class OllamaAPI {
|
||||
* 使用 ReadableStream + TextDecoder 解析 NDJSON 流
|
||||
* Ollama 流式响应格式 (NDJSON):
|
||||
* {"model":"xxx","message":{"role":"assistant","content":"Hello"},"done":false}
|
||||
*
|
||||
* @param {AbortController} [abortController] - 可选,用于强制终止流
|
||||
*/
|
||||
async chatStream(params, onChunk) {
|
||||
async chatStream(params, onChunk, abortController) {
|
||||
const body = {
|
||||
model: params.model,
|
||||
messages: params.messages,
|
||||
@@ -81,15 +83,29 @@ export class OllamaAPI {
|
||||
...(params.options && { options: params.options })
|
||||
};
|
||||
|
||||
const response = await this._request('/api/chat', {
|
||||
const fetchOptions = {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
};
|
||||
|
||||
// 注入 abort 信号,同时中止 fetch 和 reader
|
||||
if (abortController) {
|
||||
fetchOptions.signal = abortController.signal;
|
||||
}
|
||||
|
||||
const response = await this._request('/api/chat', fetchOptions);
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = '';
|
||||
|
||||
// 如果外部触发 abort,立即取消 reader(双重保险:fetch abort + reader.cancel)
|
||||
if (abortController) {
|
||||
abortController.signal.addEventListener('abort', () => {
|
||||
reader.cancel();
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
Reference in New Issue
Block a user