fix: sync stop states with composer busy

This commit is contained in:
JOJO 2025-12-14 17:35:34 +08:00
parent 55af5b52c6
commit 757e1adaae
2 changed files with 68 additions and 8 deletions

View File

@ -156,7 +156,7 @@
:input-is-multiline="inputIsMultiline"
:input-is-focused="inputIsFocused"
:is-connected="isConnected"
:streaming-message="streamingMessage"
:streaming-message="composerBusy"
:input-locked="displayLockEngaged"
:uploading="uploading"
:thinking-mode="thinkingMode"

View File

@ -111,6 +111,7 @@ const appOptions = {
return {
// 路由相关
initialRouteResolved: false,
dropToolEvents: false,
// 工具状态跟踪
preparingTools: new Map(),
@ -291,10 +292,16 @@ const appOptions = {
})
,
displayModeSwitchDisabled() {
return this.streamingMessage || this.monitorIsLocked;
return this.composerBusy;
},
displayLockEngaged() {
return this.streamingMessage || this.monitorIsLocked;
return this.composerBusy;
},
streamingUi() {
return this.streamingMessage || this.hasPendingToolActions();
},
composerBusy() {
return this.streamingUi || this.monitorIsLocked || this.stopRequested;
}
},
@ -1022,13 +1029,15 @@ const appOptions = {
this.monitorResetVisual({
preserveBubble: true,
preservePointer: true,
preserveWindows: !!options?.preserveMonitorWindows
preserveWindows: !!options?.preserveMonitorWindows,
preserveQueue: !!options?.preserveMonitorWindows
});
// 重置消息和流状态
this.streamingMessage = false;
this.currentMessageIndex = -1;
this.stopRequested = false;
this.dropToolEvents = false;
// 清理工具状态
this.toolResetTracking();
@ -1916,7 +1925,7 @@ const appOptions = {
},
handleSendOrStop() {
if (this.streamingMessage) {
if (this.composerBusy) {
this.stopTask();
} else {
this.sendMessage();
@ -1924,7 +1933,7 @@ const appOptions = {
},
sendMessage() {
if (this.streamingMessage || !this.isConnected) {
if (this.streamingUi || !this.isConnected) {
return;
}
@ -1969,11 +1978,62 @@ const appOptions = {
// 新增:停止任务方法
stopTask() {
if (this.streamingMessage && !this.stopRequested) {
const canStop = this.composerBusy && !this.stopRequested;
if (!canStop) {
return;
}
const shouldDropToolEvents = this.streamingUi;
this.stopRequested = true;
this.dropToolEvents = shouldDropToolEvents;
if (this.socket) {
this.socket.emit('stop_task');
this.stopRequested = true;
debugLog('发送停止请求');
}
// 立即清理前端状态,避免出现“不可输入也不可停止”的卡死状态
this.clearPendingTools('user_stop');
this.streamingMessage = false;
this.forceUnlockMonitor('user_stop');
},
forceUnlockMonitor(reason = 'unspecified') {
try {
this.monitorResetVisual({
preserveBubble: true,
preservePointer: true,
preserveWindows: true,
preserveQueue: false,
preservePendingResults: false,
preserveAwaitingTools: false
});
debugLog('Monitor unlocked', { reason });
} catch (error) {
console.warn('强制解锁监控面板失败', error);
}
},
clearPendingTools(reason = 'unspecified') {
debugLog('清理未完成工具', { reason });
if (Array.isArray(this.messages)) {
this.messages.forEach(msg => {
if (!msg || msg.role !== 'assistant' || !Array.isArray(msg.actions)) {
return;
}
msg.actions.forEach(action => {
if (action && action.type === 'tool' && action.tool) {
action.tool.status = action.tool.status || 'cancelled';
action.tool.awaiting_content = false;
action.streaming = false;
}
});
});
}
this.toolResetTracking();
this.preparingTools.clear();
this.activeTools.clear();
this.toolActionIndex.clear();
this.toolStacks.clear();
this.stopRequested = false;
},
async clearChat() {