fix: 修复工具调用确认后卡死问题

- 工具确认按钮添加 e.stopPropagation() 防止事件冒泡到 overlay
- 防止重复绑定 overlay click handler (initialized flag)
- 新确认打开时自动取消旧确认,防止竞态条件
- 工具执行添加 30 秒超时保护,防止 IPC 挂起
- Agent Loop 添加 5 分钟全局超时
- 每轮循环检查 abort 信号
- 工具执行失败时输出 console.error 便于调试
This commit is contained in:
Metona
2026-04-06 18:15:18 +08:00
parent 35a0c58bde
commit 43c827e9ff
2 changed files with 55 additions and 7 deletions
+20 -6
View File
@@ -7,10 +7,12 @@ import { getToolIcon, formatToolName } from '../services/tool-registry.js';
let modalEl: HTMLElement | null = null;
let resolveConfirm: ((confirmed: boolean) => void) | null = null;
let initialized = false;
export function initToolConfirmModal(): void {
modalEl = document.querySelector('#toolConfirmModal')!;
if (!modalEl) return;
if (!modalEl || initialized) return;
initialized = true;
modalEl.addEventListener('click', (e) => {
if (e.target === modalEl) {
@@ -24,9 +26,19 @@ export function showToolConfirm(call: ToolCall): Promise<boolean> {
if (!modalEl) {
modalEl = document.querySelector('#toolConfirmModal')!;
if (!modalEl) { resolve(false); return; }
modalEl.addEventListener('click', (e) => {
if (e.target === modalEl) cancelConfirm();
});
if (!initialized) {
initialized = true;
modalEl.addEventListener('click', (e) => {
if (e.target === modalEl) cancelConfirm();
});
}
}
// 如果有未完成的确认,先取消
if (resolveConfirm) {
const oldResolve = resolveConfirm;
resolveConfirm = null;
oldResolve(false);
}
resolveConfirm = resolve;
@@ -68,11 +80,13 @@ export function showToolConfirm(call: ToolCall): Promise<boolean> {
modalEl.style.display = '';
const onConfirm = () => {
const onConfirm = (e: Event) => {
e.stopPropagation();
cleanup();
resolveConfirm?.(true);
};
const onCancel = () => {
const onCancel = (e: Event) => {
e.stopPropagation();
cleanup();
resolveConfirm?.(false);
};