From 441df85e1ebd0d6f7ab376b8a32e07a6f53ec5e4 Mon Sep 17 00:00:00 2001 From: Minidoracat Date: Sat, 28 Jun 2025 07:10:15 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20=E9=87=8D=E6=96=B0=E8=AA=BF?= =?UTF-8?q?=E6=95=B4=E6=9C=83=E8=A9=B1=E8=B6=85=E6=99=82=E6=A9=9F=E5=88=B6?= =?UTF-8?q?=E3=80=81=E5=A2=9E=E5=8A=A0=E8=A8=AD=E5=AE=9A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/locales/en/translation.json | 11 +- .../web/locales/zh-CN/translation.json | 11 +- .../web/locales/zh-TW/translation.json | 12 +- .../web/models/feedback_session.py | 50 ++++++ .../web/routes/main_routes.py | 11 ++ .../web/static/css/styles.css | 64 ++++++++ .../web/static/js/app.js | 61 +++++++- .../web/static/js/modules/settings-manager.js | 83 +++++++++- .../static/js/modules/websocket-manager.js | 143 ++++++++++++++++++ .../web/templates/feedback.html | 48 +++++- 10 files changed, 480 insertions(+), 14 deletions(-) diff --git a/src/mcp_feedback_enhanced/web/locales/en/translation.json b/src/mcp_feedback_enhanced/web/locales/en/translation.json index 55454cf..863cc04 100644 --- a/src/mcp_feedback_enhanced/web/locales/en/translation.json +++ b/src/mcp_feedback_enhanced/web/locales/en/translation.json @@ -122,7 +122,13 @@ "resetError": "Error occurred while resetting settings", "timeout": "Connection Timeout (seconds)", "autorefresh": "Auto Refresh", - "debug": "Debug Mode" + "debug": "Debug Mode", + "sessionTimeoutTitle": "⏱️ Session Timeout Settings", + "sessionTimeoutEnable": "Enable Session Timeout", + "sessionTimeoutEnableDesc": "When enabled, the session will automatically close after the specified time", + "sessionTimeoutDuration": "Timeout Duration (seconds)", + "sessionTimeoutDurationDesc": "Set session timeout duration, range: 300-86400 seconds (5 minutes - 24 hours)", + "sessionTimeoutSeconds": "seconds" }, "languages": { "zh-TW": "繁體中文", @@ -200,7 +206,8 @@ "timeout": "⏰ Session has timed out, interface will close automatically", "timeoutWarning": "Session is about to timeout", "timeoutDescription": "Due to prolonged inactivity, the session has timed out. The interface will automatically close in 3 seconds.", - "closing": "Closing..." + "closing": "Closing...", + "label": "Session Timeout:" }, "autoRefresh": { "enable": "Auto Detect", diff --git a/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json b/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json index c4b90a4..e5abd99 100644 --- a/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json +++ b/src/mcp_feedback_enhanced/web/locales/zh-CN/translation.json @@ -123,7 +123,13 @@ "timeout": "连线逾时 (秒)", "autorefresh": "自动重新整理", "debug": "除错模式", - "autoCommitNoPrompt": "请先选择一个提示词作为自动提交内容" + "autoCommitNoPrompt": "请先选择一个提示词作为自动提交内容", + "sessionTimeoutTitle": "⏱️ 会话超时设置", + "sessionTimeoutEnable": "启用会话超时", + "sessionTimeoutEnableDesc": "启用后,会话将在指定时间后自动关闭", + "sessionTimeoutDuration": "超时时间(秒)", + "sessionTimeoutDurationDesc": "设置会话超时时间,范围:300-86400 秒(5分钟-24小时)", + "sessionTimeoutSeconds": "秒" }, "languages": { "zh-TW": "繁體中文", @@ -201,7 +207,8 @@ "timeout": "⏰ 会话已超时,界面将自动关闭", "timeoutWarning": "会话即将超时", "timeoutDescription": "由于长时间无响应,会话已超时。界面将在 3 秒后自动关闭。", - "closing": "正在关闭..." + "closing": "正在关闭...", + "label": "会话超时:" }, "autoRefresh": { "enable": "自动检测", diff --git a/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json b/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json index 694a433..9ff9506 100644 --- a/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json +++ b/src/mcp_feedback_enhanced/web/locales/zh-TW/translation.json @@ -128,7 +128,13 @@ "timeout": "連線逾時 (秒)", "autorefresh": "自動重新整理", "debug": "除錯模式", - "autoCommitNoPrompt": "請先選擇一個提示詞作為自動提交內容" + "autoCommitNoPrompt": "請先選擇一個提示詞作為自動提交內容", + "sessionTimeoutTitle": "⏱️ 會話超時設定", + "sessionTimeoutEnable": "啟用會話超時", + "sessionTimeoutEnableDesc": "啟用後,會話將在指定時間後自動關閉", + "sessionTimeoutDuration": "超時時間(秒)", + "sessionTimeoutDurationDesc": "設定會話超時時間,範圍:300-86400 秒(5分鐘-24小時)", + "sessionTimeoutSeconds": "秒" }, "languages": { "zh-TW": "繁體中文", @@ -206,7 +212,9 @@ "timeout": "⏰ 會話已超時,介面將自動關閉", "timeoutWarning": "會話即將超時", "timeoutDescription": "由於長時間無回應,會話已超時。介面將在 3 秒後自動關閉。", - "closing": "正在關閉..." + "closing": "正在關閉...", + "triggered": "會話已超時,程序即將關閉", + "label": "會話超時:" }, "autoRefresh": { "enable": "自動檢測", diff --git a/src/mcp_feedback_enhanced/web/models/feedback_session.py b/src/mcp_feedback_enhanced/web/models/feedback_session.py index 19de970..bc3ba57 100644 --- a/src/mcp_feedback_enhanced/web/models/feedback_session.py +++ b/src/mcp_feedback_enhanced/web/models/feedback_session.py @@ -168,6 +168,11 @@ class WebFeedbackSession: # 新增:活躍標籤頁管理 self.active_tabs: dict[str, Any] = {} + # 新增:用戶設定的會話超時 + self.user_timeout_enabled = False + self.user_timeout_seconds = 3600 # 預設 1 小時 + self.user_timeout_timer: threading.Timer | None = None + # 確保臨時目錄存在 TEMP_DIR.mkdir(parents=True, exist_ok=True) @@ -421,6 +426,39 @@ class WebFeedbackSession: ) return stats + def update_timeout_settings(self, enabled: bool, timeout_seconds: int = 3600): + """ + 更新用戶設定的會話超時 + + Args: + enabled: 是否啟用超時 + timeout_seconds: 超時秒數 + """ + debug_log(f"更新會話超時設定: enabled={enabled}, seconds={timeout_seconds}") + + # 先停止現有的計時器 + if self.user_timeout_timer: + self.user_timeout_timer.cancel() + self.user_timeout_timer = None + + self.user_timeout_enabled = enabled + self.user_timeout_seconds = timeout_seconds + + # 如果啟用且會話還在等待中,啟動計時器 + if enabled and self.status == SessionStatus.WAITING: + + def timeout_handler(): + debug_log(f"用戶設定的超時已到: {self.session_id}") + # 設置超時標誌 + self.status = SessionStatus.TIMEOUT + self.status_message = "用戶設定的會話超時" + # 設置完成事件,讓 wait_for_feedback 結束等待 + self.feedback_completed.set() + + self.user_timeout_timer = threading.Timer(timeout_seconds, timeout_handler) + self.user_timeout_timer.start() + debug_log(f"已啟動用戶超時計時器: {timeout_seconds}秒") + async def wait_for_feedback(self, timeout: int = 600) -> dict[str, Any]: """ 等待用戶回饋,包含圖片,支援超時自動清理 @@ -450,6 +488,12 @@ class WebFeedbackSession: completed = await loop.run_in_executor(None, wait_in_thread) if completed: + # 檢查是否是用戶設定的超時 + if self.status == SessionStatus.TIMEOUT and self.user_timeout_enabled: + debug_log(f"會話 {self.session_id} 因用戶設定超時而結束") + await self._cleanup_resources_on_timeout() + raise TimeoutError("會話已因用戶設定的超時而關閉") + debug_log(f"會話 {self.session_id} 收到用戶回饋") return { "logs": "\n".join(self.command_logs), @@ -753,6 +797,12 @@ class WebFeedbackSession: self.cleanup_timer = None resources_cleaned += 1 + # 1.5. 取消用戶超時計時器 + if self.user_timeout_timer: + self.user_timeout_timer.cancel() + self.user_timeout_timer = None + resources_cleaned += 1 + # 2. 關閉 WebSocket 連接 if self.websocket: try: diff --git a/src/mcp_feedback_enhanced/web/routes/main_routes.py b/src/mcp_feedback_enhanced/web/routes/main_routes.py index c3b56e4..f467b3a 100644 --- a/src/mcp_feedback_enhanced/web/routes/main_routes.py +++ b/src/mcp_feedback_enhanced/web/routes/main_routes.py @@ -672,6 +672,17 @@ async def handle_websocket_message(manager: "WebUIManager", session, data: dict) debug_log(f"收到 pong 回應,時間戳: {data.get('timestamp', 'N/A')}") # 可以在這裡記錄延遲或更新連接狀態 + elif message_type == "update_timeout_settings": + # 處理超時設定更新 + settings = data.get("settings", {}) + debug_log(f"收到超時設定更新: {settings}") + if settings.get("enabled"): + session.update_timeout_settings( + enabled=True, timeout_seconds=settings.get("seconds", 3600) + ) + else: + session.update_timeout_settings(enabled=False) + else: debug_log(f"未知的消息類型: {message_type}") diff --git a/src/mcp_feedback_enhanced/web/static/css/styles.css b/src/mcp_feedback_enhanced/web/static/css/styles.css index 8d8c80f..ee08b4d 100644 --- a/src/mcp_feedback_enhanced/web/static/css/styles.css +++ b/src/mcp_feedback_enhanced/web/static/css/styles.css @@ -2011,3 +2011,67 @@ textarea:-ms-input-placeholder, margin-bottom: 0 !important; } +/* 會話超時倒數樣式 */ +.session-timeout-display { + background: rgba(255, 193, 7, 0.1); + border: 1px solid rgba(255, 193, 7, 0.3); + border-radius: 4px; + padding: 2px 8px; +} + +.session-timeout-display .timeout-label { + font-size: 12px; + color: var(--text-secondary); + margin-right: 4px; +} + +.session-timeout-display .countdown-timer { + color: var(--text-primary); +} + +.session-timeout-display.countdown-warning .countdown-timer { + color: var(--error-color); + animation: pulse 1s ease-in-out infinite; +} + +/* 自動提交倒數樣式 */ +.auto-submit-display { + background: rgba(76, 175, 80, 0.1); + border: 1px solid rgba(76, 175, 80, 0.3); + border-radius: 4px; + padding: 2px 8px; +} + +.auto-submit-display .countdown-label { + font-size: 12px; + color: var(--text-secondary); + margin-right: 4px; +} + +.auto-submit-display .countdown-timer { + color: var(--text-primary); + font-weight: 500; +} + +/* 倒數控制按鈕 */ +.countdown-control-btn { + background: transparent; + border: none; + padding: 2px 6px; + margin-left: 4px; + cursor: pointer; + font-size: 14px; + color: var(--text-secondary); + transition: color 0.2s ease; +} + +.countdown-control-btn:hover { + color: var(--text-primary); +} + +@keyframes pulse { + 0% { opacity: 1; } + 50% { opacity: 0.6; } + 100% { opacity: 1; } +} + diff --git a/src/mcp_feedback_enhanced/web/static/js/app.js b/src/mcp_feedback_enhanced/web/static/js/app.js index 1d07f3b..6101871 100644 --- a/src/mcp_feedback_enhanced/web/static/js/app.js +++ b/src/mcp_feedback_enhanced/web/static/js/app.js @@ -271,7 +271,16 @@ } }, 800); // 延遲 800ms 確保所有初始化完成且避免與其他音效衝突 - // 17. 建立 WebSocket 連接 + // 17. 初始化會話超時設定 + if (self.settingsManager.get('sessionTimeoutEnabled')) { + const timeoutSettings = { + enabled: self.settingsManager.get('sessionTimeoutEnabled'), + seconds: self.settingsManager.get('sessionTimeoutSeconds') + }; + self.webSocketManager.updateSessionTimeoutSettings(timeoutSettings); + } + + // 18. 建立 WebSocket 連接 self.webSocketManager.connect(); resolve(); @@ -361,6 +370,9 @@ // 設置設定管理器的事件監聽器 self.settingsManager.setupEventListeners(); + // 設置用戶活動監聽(用於重置會話超時) + self.setupUserActivityListeners(); + console.log('✅ 事件監聽器設置完成'); resolve(); }); @@ -836,13 +848,20 @@ // 4. 重置回饋狀態為等待中 if (self.uiManager) { - self.uiManager.setFeedbackState( - window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, - self.currentSessionId - ); + self.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, self.currentSessionId); + } + + // 5. 重新啟動會話超時計時器(如果已啟用) + if (self.settingsManager && self.settingsManager.get('sessionTimeoutEnabled')) { + console.log('🔄 新會話創建,重新啟動會話超時計時器'); + const timeoutSettings = { + enabled: self.settingsManager.get('sessionTimeoutEnabled'), + seconds: self.settingsManager.get('sessionTimeoutSeconds') + }; + self.webSocketManager.updateSessionTimeoutSettings(timeoutSettings); } - // 5. 檢查並啟動自動提交 + // 6. 檢查並啟動自動提交 self.checkAndStartAutoSubmit(); console.log('✅ 局部更新完成,頁面已準備好接收新的回饋'); @@ -1157,6 +1176,12 @@ console.log('⏸️ 手動提交反饋,停止自動提交倒數計時器'); this.autoSubmitManager.stop(); } + + // 停止會話超時計時器 + if (this.webSocketManager) { + console.log('⏸️ 提交反饋,停止會話超時計時器'); + this.webSocketManager.stopSessionTimeout(); + } // 3. 發送回饋到 AI 助手 const success = this.webSocketManager.send({ @@ -1898,6 +1923,30 @@ } }; + /** + * 設置用戶活動監聽器(用於重置會話超時) + */ + FeedbackApp.prototype.setupUserActivityListeners = function() { + const self = this; + + // 定義需要監聽的活動事件 + const activityEvents = ['click', 'keypress', 'mousemove', 'touchstart', 'scroll']; + + // 防抖處理,避免過於頻繁地重置計時器 + const resetTimeout = window.MCPFeedback.Utils.DOM.debounce(function() { + if (self.webSocketManager) { + self.webSocketManager.resetSessionTimeout(); + } + }, 5000, false); // 5秒內的連續活動只重置一次 + + // 為每個事件添加監聽器 + activityEvents.forEach(function(eventType) { + document.addEventListener(eventType, resetTimeout, { passive: true }); + }); + + console.log('✅ 用戶活動監聽器已設置'); + }; + /** * 清理資源 */ diff --git a/src/mcp_feedback_enhanced/web/static/js/modules/settings-manager.js b/src/mcp_feedback_enhanced/web/static/js/modules/settings-manager.js index 5077116..0b76b86 100644 --- a/src/mcp_feedback_enhanced/web/static/js/modules/settings-manager.js +++ b/src/mcp_feedback_enhanced/web/static/js/modules/settings-manager.js @@ -50,7 +50,10 @@ userMessageRecordingEnabled: true, userMessagePrivacyLevel: 'full', // 'full', 'basic', 'disabled' // UI 元素尺寸設定 - combinedFeedbackTextHeight: 150 // combinedFeedbackText textarea 的高度(px) + combinedFeedbackTextHeight: 150, // combinedFeedbackText textarea 的高度(px) + // 會話超時設定 + sessionTimeoutEnabled: false, // 預設關閉 + sessionTimeoutSeconds: 3600 // 預設 1 小時(秒) }; // 當前設定 @@ -417,6 +420,9 @@ // 應用用戶訊息記錄設定 this.applyUserMessageSettings(); + + // 應用會話超時設定 + this.applySessionTimeoutSettings(); }; /** @@ -599,6 +605,28 @@ this.updatePrivacyLevelDescription(this.currentSettings.userMessagePrivacyLevel); }; + /** + * 應用會話超時設定 + */ + SettingsManager.prototype.applySessionTimeoutSettings = function() { + // 更新會話超時啟用開關 + const sessionTimeoutEnabled = Utils.safeQuerySelector('#sessionTimeoutEnabled'); + if (sessionTimeoutEnabled) { + sessionTimeoutEnabled.checked = this.currentSettings.sessionTimeoutEnabled; + } + + // 更新會話超時時間輸入框 + const sessionTimeoutSeconds = Utils.safeQuerySelector('#sessionTimeoutSeconds'); + if (sessionTimeoutSeconds) { + sessionTimeoutSeconds.value = this.currentSettings.sessionTimeoutSeconds; + } + + console.log('會話超時設定已應用到 UI:', { + enabled: this.currentSettings.sessionTimeoutEnabled, + seconds: this.currentSettings.sessionTimeoutSeconds + }); + }; + /** * 更新隱私等級描述文字 */ @@ -896,6 +924,59 @@ }); } + // 會話超時啟用開關 + const sessionTimeoutEnabled = Utils.safeQuerySelector('#sessionTimeoutEnabled'); + if (sessionTimeoutEnabled) { + sessionTimeoutEnabled.addEventListener('change', function() { + const newValue = sessionTimeoutEnabled.checked; + self.set('sessionTimeoutEnabled', newValue); + console.log('會話超時狀態已更新:', newValue); + + // 觸發 WebSocket 通知後端更新超時設定 + if (window.MCPFeedback && window.MCPFeedback.app && window.MCPFeedback.app.webSocketManager) { + window.MCPFeedback.app.webSocketManager.send({ + type: 'update_timeout_settings', + settings: { + enabled: newValue, + seconds: self.get('sessionTimeoutSeconds') + } + }); + } + }); + } + + // 會話超時時間設定 + const sessionTimeoutSeconds = Utils.safeQuerySelector('#sessionTimeoutSeconds'); + if (sessionTimeoutSeconds) { + sessionTimeoutSeconds.addEventListener('change', function(e) { + const seconds = parseInt(e.target.value); + + // 驗證輸入值範圍 + if (isNaN(seconds) || seconds < 300) { + e.target.value = 300; + self.set('sessionTimeoutSeconds', 300); + } else if (seconds > 86400) { + e.target.value = 86400; + self.set('sessionTimeoutSeconds', 86400); + } else { + self.set('sessionTimeoutSeconds', seconds); + } + + console.log('會話超時時間已更新:', self.get('sessionTimeoutSeconds'), '秒'); + + // 觸發 WebSocket 通知後端更新超時設定 + if (window.MCPFeedback && window.MCPFeedback.app && window.MCPFeedback.app.webSocketManager) { + window.MCPFeedback.app.webSocketManager.send({ + type: 'update_timeout_settings', + settings: { + enabled: self.get('sessionTimeoutEnabled'), + seconds: self.get('sessionTimeoutSeconds') + } + }); + } + }); + } + // 重置設定 const resetBtn = Utils.safeQuerySelector('#resetSettingsBtn'); if (resetBtn) { diff --git a/src/mcp_feedback_enhanced/web/static/js/modules/websocket-manager.js b/src/mcp_feedback_enhanced/web/static/js/modules/websocket-manager.js index c48d8c0..e9f1544 100644 --- a/src/mcp_feedback_enhanced/web/static/js/modules/websocket-manager.js +++ b/src/mcp_feedback_enhanced/web/static/js/modules/websocket-manager.js @@ -47,6 +47,15 @@ // 網路狀態檢測 this.networkOnline = navigator.onLine; this.setupNetworkStatusDetection(); + + // 會話超時計時器 + this.sessionTimeoutTimer = null; + this.sessionTimeoutInterval = null; // 用於更新倒數顯示 + this.sessionTimeoutRemaining = 0; // 剩餘秒數 + this.sessionTimeoutSettings = { + enabled: false, + seconds: 3600 + }; } /** @@ -285,6 +294,12 @@ timestamp: data.timestamp }); break; + case 'update_timeout_settings': + // 處理超時設定更新 + if (data.settings) { + this.updateSessionTimeoutSettings(data.settings); + } + break; default: // 其他訊息類型由外部處理 break; @@ -461,11 +476,139 @@ return true; }; + /** + * 更新會話超時設定 + */ + WebSocketManager.prototype.updateSessionTimeoutSettings = function(settings) { + this.sessionTimeoutSettings = settings; + console.log('會話超時設定已更新:', settings); + + // 重新啟動計時器 + if (settings.enabled) { + this.startSessionTimeout(); + } else { + this.stopSessionTimeout(); + } + }; + + /** + * 啟動會話超時計時器 + */ + WebSocketManager.prototype.startSessionTimeout = function() { + // 先停止現有計時器 + this.stopSessionTimeout(); + + if (!this.sessionTimeoutSettings.enabled) { + return; + } + + const timeoutSeconds = this.sessionTimeoutSettings.seconds; + this.sessionTimeoutRemaining = timeoutSeconds; + + console.log('啟動會話超時計時器:', timeoutSeconds, '秒'); + + // 顯示倒數計時器 + const displayElement = document.getElementById('sessionTimeoutDisplay'); + if (displayElement) { + displayElement.style.display = ''; + } + + const self = this; + + // 更新倒數顯示 + function updateDisplay() { + const minutes = Math.floor(self.sessionTimeoutRemaining / 60); + const seconds = self.sessionTimeoutRemaining % 60; + const displayText = minutes.toString().padStart(2, '0') + ':' + + seconds.toString().padStart(2, '0'); + + const timerElement = document.getElementById('sessionTimeoutTimer'); + if (timerElement) { + timerElement.textContent = displayText; + } + + // 當剩餘時間少於60秒時,改變顯示樣式 + if (self.sessionTimeoutRemaining < 60 && displayElement) { + displayElement.classList.add('countdown-warning'); + } + } + + // 立即更新一次顯示 + updateDisplay(); + + // 每秒更新倒數 + this.sessionTimeoutInterval = setInterval(function() { + self.sessionTimeoutRemaining--; + updateDisplay(); + + if (self.sessionTimeoutRemaining <= 0) { + clearInterval(self.sessionTimeoutInterval); + self.sessionTimeoutInterval = null; + + console.log('會話超時,準備關閉程序'); + + // 發送超時通知給後端 + if (self.isConnected) { + self.send({ + type: 'user_timeout', + timestamp: Date.now() + }); + } + + // 顯示超時訊息 + const timeoutMessage = window.i18nManager ? + window.i18nManager.t('sessionTimeout.triggered', '會話已超時,程序即將關閉') : + '會話已超時,程序即將關閉'; + Utils.showMessage(timeoutMessage, Utils.CONSTANTS.MESSAGE_WARNING); + + // 延遲關閉,讓用戶看到訊息 + setTimeout(function() { + window.close(); + }, 3000); + } + }, 1000); + }; + + /** + * 停止會話超時計時器 + */ + WebSocketManager.prototype.stopSessionTimeout = function() { + if (this.sessionTimeoutTimer) { + clearTimeout(this.sessionTimeoutTimer); + this.sessionTimeoutTimer = null; + } + + if (this.sessionTimeoutInterval) { + clearInterval(this.sessionTimeoutInterval); + this.sessionTimeoutInterval = null; + } + + // 隱藏倒數顯示 + const displayElement = document.getElementById('sessionTimeoutDisplay'); + if (displayElement) { + displayElement.style.display = 'none'; + displayElement.classList.remove('countdown-warning'); + } + + console.log('會話超時計時器已停止'); + }; + + /** + * 重置會話超時計時器(用戶有活動時調用) + */ + WebSocketManager.prototype.resetSessionTimeout = function() { + if (this.sessionTimeoutSettings.enabled) { + console.log('重置會話超時計時器'); + this.startSessionTimeout(); + } + }; + /** * 關閉連接 */ WebSocketManager.prototype.close = function() { this.stopHeartbeat(); + this.stopSessionTimeout(); if (this.websocket) { this.websocket.close(); this.websocket = null; diff --git a/src/mcp_feedback_enhanced/web/templates/feedback.html b/src/mcp_feedback_enhanced/web/templates/feedback.html index eec4258..de97476 100644 --- a/src/mcp_feedback_enhanced/web/templates/feedback.html +++ b/src/mcp_feedback_enhanced/web/templates/feedback.html @@ -429,9 +429,10 @@ - + +
+
+

⏱️ 會話超時設定

+
+
+
+
+
啟用會話超時
+
+ 啟用後,會話將在指定時間後自動關閉 +
+
+
+ +
+
+ +
+
+
超時時間(秒)
+
+ 設定會話超時時間,範圍:300-86400 秒(5分鐘-24小時) +
+
+
+ + +
+
+
+
+