修复: AI工具OOM/路径遍历+续跑锁收敛+UX交互批
This commit is contained in:
@@ -480,6 +480,13 @@ async function sendQueuedNow(index: number) {
|
||||
|
||||
/** 停止当前生成:本地先复位 streaming,再发停止信号。
|
||||
* 不依赖后端 AiCompleted 收尾——审批态看门狗已 clear(useAiEvents),若 AiCompleted 竞态丢失则 streaming 永久 true 卡死,故本地兜底。
|
||||
*
|
||||
* UX-260617-19: stop IPC 失败时的兜底。本地已先置 streaming=false,但若 stop 信号未送达后端,
|
||||
* 后端会继续生成并发回 delta/Completed 事件,与用户已感知的「已停止」语义冲突;更坏情况是
|
||||
* 后端 hang 既不收尾也不发事件(stop_flag 未置位、无 watchdog 兜底则无恢复路径)。
|
||||
* 故 stop 失败时不 clearStreamWatchdog,反而重启看门狗:后端若继续生成,活跃 delta 会不断重置它
|
||||
* 不误触发;后端若真 hang,130s 后 onStreamTimeout 兜底复位 streaming+清队列+推错误气泡。
|
||||
* 同时推一条 stopLoopFailed 错误消息让用户知晓停止未生效(可再点或等待收尾)。
|
||||
*/
|
||||
async function stopChat() {
|
||||
state.streaming = false // 本地先复位,不依赖后端 AiCompleted(审批态看门狗已 clear,竞态丢失则卡死)
|
||||
@@ -487,7 +494,22 @@ async function stopChat() {
|
||||
// UX-260616-05 决策 a(逐条续发):不再清队列,保留供 AiCompleted 链式触发 drainQueue 续发。
|
||||
// 后端 agentic.rs:190 emit AiCompleted 注释明确「保证前端收事件时后端已可接下一条,队列续发不被拒」;
|
||||
// 当前未完成回复已入库(agentic.rs:185 save_conversation)保留为截断回复。
|
||||
await aiApi.stopChat()
|
||||
try {
|
||||
await aiApi.stopChat()
|
||||
} catch (e) {
|
||||
// stop 信号未送达后端:重启看门狗(后端继续生成时活跃事件会重置它,真 hang 则 130s 后兜底收尾),
|
||||
// 避免后端仍在跑却无任何恢复路径(原 clearStreamWatchdog 已把兜底关掉)。
|
||||
resetStreamWatchdog()
|
||||
const errMsg = e instanceof Error ? e.message : String(e)
|
||||
state.messages.push({
|
||||
id: `stop-err-${nextMsgId()}`,
|
||||
role: 'assistant',
|
||||
content: t('aiChat.stopLoopFailed', { msg: errMsg }),
|
||||
isError: true,
|
||||
timestamp: Date.now(),
|
||||
} as AiMessage)
|
||||
console.error('[AI] stopChat IPC 失败,已重启看门狗兜底:', e)
|
||||
}
|
||||
}
|
||||
|
||||
export function useAiSend() {
|
||||
|
||||
Reference in New Issue
Block a user